Name: Kapil Wanaskar¶

Student ID: 016649880¶

ISE 244¶

Transfer learning and fine-tuning¶

In this tutorial, you will learn how to classify images of cats and dogs by using transfer learning from a pre-trained network.

A pre-trained model is a saved network that was previously trained on a large dataset, typically on a large-scale image-classification task. You either use the pretrained model as is or use transfer learning to customize this model to a given task.

The intuition behind transfer learning for image classification is that if a model is trained on a large and general enough dataset, this model will effectively serve as a generic model of the visual world. You can then take advantage of these learned feature maps without having to start from scratch by training a large model on a large dataset.

In this notebook, you will try two ways to customize a pretrained model:

  1. Feature Extraction: Use the representations learned by a previous network to extract meaningful features from new samples. You simply add a new classifier, which will be trained from scratch, on top of the pretrained model so that you can repurpose the feature maps learned previously for the dataset.

    You do not need to (re)train the entire model. The base convolutional network already contains features that are generically useful for classifying pictures. However, the final, classification part of the pretrained model is specific to the original classification task, and subsequently specific to the set of classes on which the model was trained.

  2. Fine-Tuning: Unfreeze a few of the top layers of a frozen model base and jointly train both the newly-added classifier layers and the last layers of the base model. This allows us to "fine-tune" the higher-order feature representations in the base model in order to make them more relevant for the specific task.

You will follow the general machine learning workflow.

  1. Examine and understand the data
  2. Build an input pipeline, in this case using Keras ImageDataGenerator
  3. Compose the model
    • Load in the pretrained base model (and pretrained weights)
    • Stack the classification layers on top
  4. Train the model
  5. Evaluate model
In [ ]:
import matplotlib.pyplot as plt
import numpy as np
import os
import tensorflow as tf
In [ ]:
_URL = 'https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip'
path_to_zip = tf.keras.utils.get_file('cats_and_dogs.zip', origin=_URL, extract=True)
PATH = os.path.join(os.path.dirname(path_to_zip), 'cats_and_dogs_filtered')
In [ ]:
train_dir = os.path.join(PATH, 'train')
validation_dir = os.path.join(PATH, 'validation')

BATCH_SIZE = 32
IMG_SIZE = (160, 160)

train_dataset = tf.keras.utils.image_dataset_from_directory(train_dir,
                                                            shuffle=True,
                                                            batch_size=BATCH_SIZE,
                                                            image_size=IMG_SIZE)
Found 2000 files belonging to 2 classes.
In [ ]:
validation_dataset = tf.keras.utils.image_dataset_from_directory(validation_dir,
                                                                    shuffle=True,
                                                                    batch_size=BATCH_SIZE,
                                                                    image_size=IMG_SIZE)
Found 1000 files belonging to 2 classes.

Show the first nine images and labels from the training set:

In [ ]:
class_names = train_dataset.class_names

plt.figure(figsize=(10, 10))
for images, labels in train_dataset.take(1):
    for i in range(9):
        ax = plt.subplot(3, 3, i + 1)
        plt.imshow(images[i].numpy().astype("uint8"))
        plt.title(class_names[labels[i]])
        plt.axis("off")
2024-03-27 03:29:58.022130: W tensorflow/core/framework/local_rendezvous.cc:404] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence

As the original dataset doesn't contain a test set, you will create one. To do so, determine how many batches of data are available in the validation set using tf.data.experimental.cardinality, then move 20% of them to a test set.

In [ ]:
val_batches = tf.data.experimental.cardinality(validation_dataset)
test_dataset = validation_dataset.take(val_batches // 5)
validation_dataset = validation_dataset.skip(val_batches // 5)
In [ ]:
print("Number of validation batches: %d" % tf.data.experimental.cardinality(validation_dataset))
print("Number of test batches: %d" % tf.data.experimental.cardinality(test_dataset))
Number of validation batches: 26
Number of test batches: 6

Configure the dataset for performance¶

Use buffered prefetching to load images from disk without having I/O become blocking. To learn more about this method see the data performance guide.

In [ ]:
AUTOTUNE = tf.data.AUTOTUNE

train_dataset = train_dataset.prefetch(buffer_size=AUTOTUNE)
validation_dataset = validation_dataset.prefetch(buffer_size=AUTOTUNE)
test_dataset = test_dataset.prefetch(buffer_size=AUTOTUNE)

Use data augmentation¶

When you don't have a large image dataset, it's a good practice to artificially introduce sample diversity by applying random, yet realistic, transformations to the training images, such as rotation and horizontal flipping. This helps expose the model to different aspects of the training data and reduce overfitting. You can learn more about data augmentation in this tutorial.

In [ ]:
data_augmentation = tf.keras.Sequential([
    tf.keras.layers.RandomFlip("horizontal"),
    tf.keras.layers.RandomRotation(0.2),
])

Note: These layers are active only during training, when you call Model.fit. They are inactive when the model is used in inference mode in Model.evaluate, Model.predict, or Model.call.

Let's repeatedly apply these layers to the same image and see the result.

In [ ]:
for image, _ in train_dataset.take(1):
    plt.figure(figsize=(10, 10))
    first_image = image[0]
    for i in range(9):
        ax = plt.subplot(3, 3, i + 1)
        augmented_image = data_augmentation(tf.expand_dims(first_image, 0))
        plt.imshow(augmented_image[0] / 255)
        plt.axis('off')
2024-03-27 03:29:58.836941: W tensorflow/core/framework/local_rendezvous.cc:404] Local rendezvous is aborting with status: OUT_OF_RANGE: End of sequence

Rescale pixel values¶

In a moment, you will download tf.keras.applications.MobileNetV2 for use as your base model. This model expects pixel values in [-1, 1], but at this point, the pixel values in your images are in [0, 255]. To rescale them, use the preprocessing method included with the model.

In [ ]:
preprocess_input_v1 = tf.keras.applications.mobilenet.preprocess_input
preprocess_input_v2 = tf.keras.applications.mobilenet_v2.preprocess_input
preprocess_input_v3 = tf.keras.applications.mobilenet_v3.preprocess_input

Note: Alternatively, you could rescale pixel values from [0, 255] to [-1, 1] using tf.keras.layers.Rescaling.

In [ ]:
rescale = tf.keras.layers.Rescaling(1./127.5, offset=-1)

Note: If using other tf.keras.applications, be sure to check the API doc to determine if they expect pixels in [-1, 1] or [0, 1], or use the included preprocess_input function.

Create the base model from the pre-trained convnets¶

You will create the base model from the MobileNet V2 model developed at Google. This is pre-trained on the ImageNet dataset, a large dataset consisting of 1.4M images and 1000 classes. ImageNet is a research training dataset with a wide variety of categories like jackfruit and syringe. This base of knowledge will help us classify cats and dogs from our specific dataset.

First, you need to pick which layer of MobileNet V2 you will use for feature extraction. The very last classification layer (on "top", as most diagrams of machine learning models go from bottom to top) is not very useful. Instead, you will follow the common practice to depend on the very last layer before the flatten operation. This layer is called the "bottleneck layer". The bottleneck layer features retain more generality as compared to the final/top layer.

First, instantiate a MobileNet V2 model pre-loaded with weights trained on ImageNet. By specifying the include_top=False argument, you load a network that doesn't include the classification layers at the top, which is ideal for feature extraction.

In [ ]:
# Create the base model from the pre-trained models MobileNet, MobileNet V2, and MobileNet V3
IMG_SHAPE = IMG_SIZE + (3,)

# Creating the base model from MobileNet.
base_model_v1 = tf.keras.applications.MobileNet(input_shape=IMG_SHAPE,
                                                include_top=False,
                                                weights='imagenet')


# Creating the base model from MobileNet V2.
base_model_v2 = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,
                                                  include_top=False,
                                                  weights='imagenet')

# Creating the base model from MobileNet V3 Large.
base_model_v3 = tf.keras.applications.MobileNetV3Large(input_shape=IMG_SHAPE,
                                                       include_top=False,
                                                         weights='imagenet')
/Users/kapilwanaskar/anaconda3/lib/python3.11/site-packages/keras/src/applications/mobilenet_v3.py:512: UserWarning: `input_shape` is undefined or non-square, or `rows` is not 224. Weights for input shape (224, 224) will be loaded as the default.
  return MobileNetV3(

This feature extractor converts each 160x160x3 image into a 5x5x1280 block of features. Let's see what it does to an example batch of images:

In [ ]:
image_batch, label_batch = next(iter(train_dataset))
feature_batch_v1 = base_model_v1(image_batch)
feature_batch_v2 = base_model_v2(image_batch)
feature_batch_v3 = base_model_v3(image_batch)

print("MobileNet Feature Batch Shape:", feature_batch_v1.shape)
print("MobileNetV2 Feature Batch Shape:", feature_batch_v2.shape)
print("MobileNetV3 Feature Batch Shape:", feature_batch_v3.shape)
MobileNet Feature Batch Shape: (32, 5, 5, 1024)
MobileNetV2 Feature Batch Shape: (32, 5, 5, 1280)
MobileNetV3 Feature Batch Shape: (32, 5, 5, 960)

Feature extraction¶

In this step, you will freeze the convolutional base created from the previous step and to use as a feature extractor. Additionally, you add a classifier on top of it and train the top-level classifier.

Freeze the convolutional base¶

It is important to freeze the convolutional base before you compile and train the model. Freezing (by setting layer.trainable = False) prevents the weights in a given layer from being updated during training. MobileNet V2 has many layers, so setting the entire model's trainable flag to False will freeze all of them.

In [ ]:
base_model_v1.trainable = False
base_model_v2.trainable = False
base_model_v3.trainable = False

Important note about BatchNormalization layers¶

Many models contain tf.keras.layers.BatchNormalization layers. This layer is a special case and precautions should be taken in the context of fine-tuning, as shown later in this tutorial.

When you set layer.trainable = False, the BatchNormalization layer will run in inference mode, and will not update its mean and variance statistics.

When you unfreeze a model that contains BatchNormalization layers in order to do fine-tuning, you should keep the BatchNormalization layers in inference mode by passing training = False when calling the base model. Otherwise, the updates applied to the non-trainable weights will destroy what the model has learned.

For more details, see the Transfer learning guide.

In [ ]:
# Let's take a look at the base model architecture for both models
print("\nMobileNet Architecture")
base_model_v1.summary()

print("MobileNetV2 Architecture")
base_model_v2.summary()

print("MobileNetV3 Architecture")
base_model_v3.summary()
MobileNet Architecture
Model: "mobilenet_1.00_160"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type)                    ┃ Output Shape           ┃       Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ input_layer_36 (InputLayer)     │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv1 (Conv2D)                  │ (None, 80, 80, 32)     │           864 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv1_bn (BatchNormalization)   │ (None, 80, 80, 32)     │           128 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv1_relu (ReLU)               │ (None, 80, 80, 32)     │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_1 (DepthwiseConv2D)     │ (None, 80, 80, 32)     │           288 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_1_bn                    │ (None, 80, 80, 32)     │           128 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_1_relu (ReLU)           │ (None, 80, 80, 32)     │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_1 (Conv2D)              │ (None, 80, 80, 64)     │         2,048 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_1_bn                    │ (None, 80, 80, 64)     │           256 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_1_relu (ReLU)           │ (None, 80, 80, 64)     │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pad_2 (ZeroPadding2D)      │ (None, 81, 81, 64)     │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_2 (DepthwiseConv2D)     │ (None, 40, 40, 64)     │           576 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_2_bn                    │ (None, 40, 40, 64)     │           256 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_2_relu (ReLU)           │ (None, 40, 40, 64)     │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_2 (Conv2D)              │ (None, 40, 40, 128)    │         8,192 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_2_bn                    │ (None, 40, 40, 128)    │           512 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_2_relu (ReLU)           │ (None, 40, 40, 128)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_3 (DepthwiseConv2D)     │ (None, 40, 40, 128)    │         1,152 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_3_bn                    │ (None, 40, 40, 128)    │           512 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_3_relu (ReLU)           │ (None, 40, 40, 128)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_3 (Conv2D)              │ (None, 40, 40, 128)    │        16,384 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_3_bn                    │ (None, 40, 40, 128)    │           512 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_3_relu (ReLU)           │ (None, 40, 40, 128)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pad_4 (ZeroPadding2D)      │ (None, 41, 41, 128)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_4 (DepthwiseConv2D)     │ (None, 20, 20, 128)    │         1,152 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_4_bn                    │ (None, 20, 20, 128)    │           512 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_4_relu (ReLU)           │ (None, 20, 20, 128)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_4 (Conv2D)              │ (None, 20, 20, 256)    │        32,768 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_4_bn                    │ (None, 20, 20, 256)    │         1,024 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_4_relu (ReLU)           │ (None, 20, 20, 256)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_5 (DepthwiseConv2D)     │ (None, 20, 20, 256)    │         2,304 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_5_bn                    │ (None, 20, 20, 256)    │         1,024 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_5_relu (ReLU)           │ (None, 20, 20, 256)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_5 (Conv2D)              │ (None, 20, 20, 256)    │        65,536 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_5_bn                    │ (None, 20, 20, 256)    │         1,024 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_5_relu (ReLU)           │ (None, 20, 20, 256)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pad_6 (ZeroPadding2D)      │ (None, 21, 21, 256)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_6 (DepthwiseConv2D)     │ (None, 10, 10, 256)    │         2,304 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_6_bn                    │ (None, 10, 10, 256)    │         1,024 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_6_relu (ReLU)           │ (None, 10, 10, 256)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_6 (Conv2D)              │ (None, 10, 10, 512)    │       131,072 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_6_bn                    │ (None, 10, 10, 512)    │         2,048 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_6_relu (ReLU)           │ (None, 10, 10, 512)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_7 (DepthwiseConv2D)     │ (None, 10, 10, 512)    │         4,608 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_7_bn                    │ (None, 10, 10, 512)    │         2,048 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_7_relu (ReLU)           │ (None, 10, 10, 512)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_7 (Conv2D)              │ (None, 10, 10, 512)    │       262,144 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_7_bn                    │ (None, 10, 10, 512)    │         2,048 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_7_relu (ReLU)           │ (None, 10, 10, 512)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_8 (DepthwiseConv2D)     │ (None, 10, 10, 512)    │         4,608 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_8_bn                    │ (None, 10, 10, 512)    │         2,048 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_8_relu (ReLU)           │ (None, 10, 10, 512)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_8 (Conv2D)              │ (None, 10, 10, 512)    │       262,144 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_8_bn                    │ (None, 10, 10, 512)    │         2,048 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_8_relu (ReLU)           │ (None, 10, 10, 512)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_9 (DepthwiseConv2D)     │ (None, 10, 10, 512)    │         4,608 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_9_bn                    │ (None, 10, 10, 512)    │         2,048 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_9_relu (ReLU)           │ (None, 10, 10, 512)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_9 (Conv2D)              │ (None, 10, 10, 512)    │       262,144 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_9_bn                    │ (None, 10, 10, 512)    │         2,048 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_9_relu (ReLU)           │ (None, 10, 10, 512)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_10 (DepthwiseConv2D)    │ (None, 10, 10, 512)    │         4,608 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_10_bn                   │ (None, 10, 10, 512)    │         2,048 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_10_relu (ReLU)          │ (None, 10, 10, 512)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_10 (Conv2D)             │ (None, 10, 10, 512)    │       262,144 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_10_bn                   │ (None, 10, 10, 512)    │         2,048 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_10_relu (ReLU)          │ (None, 10, 10, 512)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_11 (DepthwiseConv2D)    │ (None, 10, 10, 512)    │         4,608 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_11_bn                   │ (None, 10, 10, 512)    │         2,048 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_11_relu (ReLU)          │ (None, 10, 10, 512)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_11 (Conv2D)             │ (None, 10, 10, 512)    │       262,144 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_11_bn                   │ (None, 10, 10, 512)    │         2,048 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_11_relu (ReLU)          │ (None, 10, 10, 512)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pad_12 (ZeroPadding2D)     │ (None, 11, 11, 512)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_12 (DepthwiseConv2D)    │ (None, 5, 5, 512)      │         4,608 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_12_bn                   │ (None, 5, 5, 512)      │         2,048 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_12_relu (ReLU)          │ (None, 5, 5, 512)      │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_12 (Conv2D)             │ (None, 5, 5, 1024)     │       524,288 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_12_bn                   │ (None, 5, 5, 1024)     │         4,096 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_12_relu (ReLU)          │ (None, 5, 5, 1024)     │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_13 (DepthwiseConv2D)    │ (None, 5, 5, 1024)     │         9,216 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_13_bn                   │ (None, 5, 5, 1024)     │         4,096 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_dw_13_relu (ReLU)          │ (None, 5, 5, 1024)     │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_13 (Conv2D)             │ (None, 5, 5, 1024)     │     1,048,576 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_13_bn                   │ (None, 5, 5, 1024)     │         4,096 │
│ (BatchNormalization)            │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ conv_pw_13_relu (ReLU)          │ (None, 5, 5, 1024)     │             0 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
 Total params: 3,228,864 (12.32 MB)
 Trainable params: 0 (0.00 B)
 Non-trainable params: 3,228,864 (12.32 MB)
MobileNetV2 Architecture
Model: "mobilenetv2_1.00_160"
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ Layer (type)        ┃ Output Shape      ┃    Param # ┃ Connected to      ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ input_layer_37      │ (None, 160, 160,  │          0 │ -                 │
│ (InputLayer)        │ 3)                │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ Conv1 (Conv2D)      │ (None, 80, 80,    │        864 │ input_layer_37[0… │
│                     │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ bn_Conv1            │ (None, 80, 80,    │        128 │ Conv1[0][0]       │
│ (BatchNormalizatio… │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ Conv1_relu (ReLU)   │ (None, 80, 80,    │          0 │ bn_Conv1[0][0]    │
│                     │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_dept… │ (None, 80, 80,    │        288 │ Conv1_relu[0][0]  │
│ (DepthwiseConv2D)   │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_dept… │ (None, 80, 80,    │        128 │ expanded_conv_de… │
│ (BatchNormalizatio… │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_dept… │ (None, 80, 80,    │          0 │ expanded_conv_de… │
│ (ReLU)              │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_proj… │ (None, 80, 80,    │        512 │ expanded_conv_de… │
│ (Conv2D)            │ 16)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_proj… │ (None, 80, 80,    │         64 │ expanded_conv_pr… │
│ (BatchNormalizatio… │ 16)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_1_expand      │ (None, 80, 80,    │      1,536 │ expanded_conv_pr… │
│ (Conv2D)            │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_1_expand_BN   │ (None, 80, 80,    │        384 │ block_1_expand[0… │
│ (BatchNormalizatio… │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_1_expand_relu │ (None, 80, 80,    │          0 │ block_1_expand_B… │
│ (ReLU)              │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_1_pad         │ (None, 81, 81,    │          0 │ block_1_expand_r… │
│ (ZeroPadding2D)     │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_1_depthwise   │ (None, 40, 40,    │        864 │ block_1_pad[0][0] │
│ (DepthwiseConv2D)   │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_1_depthwise_… │ (None, 40, 40,    │        384 │ block_1_depthwis… │
│ (BatchNormalizatio… │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_1_depthwise_… │ (None, 40, 40,    │          0 │ block_1_depthwis… │
│ (ReLU)              │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_1_project     │ (None, 40, 40,    │      2,304 │ block_1_depthwis… │
│ (Conv2D)            │ 24)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_1_project_BN  │ (None, 40, 40,    │         96 │ block_1_project[… │
│ (BatchNormalizatio… │ 24)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_2_expand      │ (None, 40, 40,    │      3,456 │ block_1_project_… │
│ (Conv2D)            │ 144)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_2_expand_BN   │ (None, 40, 40,    │        576 │ block_2_expand[0… │
│ (BatchNormalizatio… │ 144)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_2_expand_relu │ (None, 40, 40,    │          0 │ block_2_expand_B… │
│ (ReLU)              │ 144)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_2_depthwise   │ (None, 40, 40,    │      1,296 │ block_2_expand_r… │
│ (DepthwiseConv2D)   │ 144)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_2_depthwise_… │ (None, 40, 40,    │        576 │ block_2_depthwis… │
│ (BatchNormalizatio… │ 144)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_2_depthwise_… │ (None, 40, 40,    │          0 │ block_2_depthwis… │
│ (ReLU)              │ 144)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_2_project     │ (None, 40, 40,    │      3,456 │ block_2_depthwis… │
│ (Conv2D)            │ 24)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_2_project_BN  │ (None, 40, 40,    │         96 │ block_2_project[… │
│ (BatchNormalizatio… │ 24)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_2_add (Add)   │ (None, 40, 40,    │          0 │ block_1_project_… │
│                     │ 24)               │            │ block_2_project_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_3_expand      │ (None, 40, 40,    │      3,456 │ block_2_add[0][0] │
│ (Conv2D)            │ 144)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_3_expand_BN   │ (None, 40, 40,    │        576 │ block_3_expand[0… │
│ (BatchNormalizatio… │ 144)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_3_expand_relu │ (None, 40, 40,    │          0 │ block_3_expand_B… │
│ (ReLU)              │ 144)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_3_pad         │ (None, 41, 41,    │          0 │ block_3_expand_r… │
│ (ZeroPadding2D)     │ 144)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_3_depthwise   │ (None, 20, 20,    │      1,296 │ block_3_pad[0][0] │
│ (DepthwiseConv2D)   │ 144)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_3_depthwise_… │ (None, 20, 20,    │        576 │ block_3_depthwis… │
│ (BatchNormalizatio… │ 144)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_3_depthwise_… │ (None, 20, 20,    │          0 │ block_3_depthwis… │
│ (ReLU)              │ 144)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_3_project     │ (None, 20, 20,    │      4,608 │ block_3_depthwis… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_3_project_BN  │ (None, 20, 20,    │        128 │ block_3_project[… │
│ (BatchNormalizatio… │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_4_expand      │ (None, 20, 20,    │      6,144 │ block_3_project_… │
│ (Conv2D)            │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_4_expand_BN   │ (None, 20, 20,    │        768 │ block_4_expand[0… │
│ (BatchNormalizatio… │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_4_expand_relu │ (None, 20, 20,    │          0 │ block_4_expand_B… │
│ (ReLU)              │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_4_depthwise   │ (None, 20, 20,    │      1,728 │ block_4_expand_r… │
│ (DepthwiseConv2D)   │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_4_depthwise_… │ (None, 20, 20,    │        768 │ block_4_depthwis… │
│ (BatchNormalizatio… │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_4_depthwise_… │ (None, 20, 20,    │          0 │ block_4_depthwis… │
│ (ReLU)              │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_4_project     │ (None, 20, 20,    │      6,144 │ block_4_depthwis… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_4_project_BN  │ (None, 20, 20,    │        128 │ block_4_project[… │
│ (BatchNormalizatio… │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_4_add (Add)   │ (None, 20, 20,    │          0 │ block_3_project_… │
│                     │ 32)               │            │ block_4_project_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_5_expand      │ (None, 20, 20,    │      6,144 │ block_4_add[0][0] │
│ (Conv2D)            │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_5_expand_BN   │ (None, 20, 20,    │        768 │ block_5_expand[0… │
│ (BatchNormalizatio… │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_5_expand_relu │ (None, 20, 20,    │          0 │ block_5_expand_B… │
│ (ReLU)              │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_5_depthwise   │ (None, 20, 20,    │      1,728 │ block_5_expand_r… │
│ (DepthwiseConv2D)   │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_5_depthwise_… │ (None, 20, 20,    │        768 │ block_5_depthwis… │
│ (BatchNormalizatio… │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_5_depthwise_… │ (None, 20, 20,    │          0 │ block_5_depthwis… │
│ (ReLU)              │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_5_project     │ (None, 20, 20,    │      6,144 │ block_5_depthwis… │
│ (Conv2D)            │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_5_project_BN  │ (None, 20, 20,    │        128 │ block_5_project[… │
│ (BatchNormalizatio… │ 32)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_5_add (Add)   │ (None, 20, 20,    │          0 │ block_4_add[0][0… │
│                     │ 32)               │            │ block_5_project_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_6_expand      │ (None, 20, 20,    │      6,144 │ block_5_add[0][0] │
│ (Conv2D)            │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_6_expand_BN   │ (None, 20, 20,    │        768 │ block_6_expand[0… │
│ (BatchNormalizatio… │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_6_expand_relu │ (None, 20, 20,    │          0 │ block_6_expand_B… │
│ (ReLU)              │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_6_pad         │ (None, 21, 21,    │          0 │ block_6_expand_r… │
│ (ZeroPadding2D)     │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_6_depthwise   │ (None, 10, 10,    │      1,728 │ block_6_pad[0][0] │
│ (DepthwiseConv2D)   │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_6_depthwise_… │ (None, 10, 10,    │        768 │ block_6_depthwis… │
│ (BatchNormalizatio… │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_6_depthwise_… │ (None, 10, 10,    │          0 │ block_6_depthwis… │
│ (ReLU)              │ 192)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_6_project     │ (None, 10, 10,    │     12,288 │ block_6_depthwis… │
│ (Conv2D)            │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_6_project_BN  │ (None, 10, 10,    │        256 │ block_6_project[… │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_7_expand      │ (None, 10, 10,    │     24,576 │ block_6_project_… │
│ (Conv2D)            │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_7_expand_BN   │ (None, 10, 10,    │      1,536 │ block_7_expand[0… │
│ (BatchNormalizatio… │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_7_expand_relu │ (None, 10, 10,    │          0 │ block_7_expand_B… │
│ (ReLU)              │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_7_depthwise   │ (None, 10, 10,    │      3,456 │ block_7_expand_r… │
│ (DepthwiseConv2D)   │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_7_depthwise_… │ (None, 10, 10,    │      1,536 │ block_7_depthwis… │
│ (BatchNormalizatio… │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_7_depthwise_… │ (None, 10, 10,    │          0 │ block_7_depthwis… │
│ (ReLU)              │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_7_project     │ (None, 10, 10,    │     24,576 │ block_7_depthwis… │
│ (Conv2D)            │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_7_project_BN  │ (None, 10, 10,    │        256 │ block_7_project[… │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_7_add (Add)   │ (None, 10, 10,    │          0 │ block_6_project_… │
│                     │ 64)               │            │ block_7_project_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_8_expand      │ (None, 10, 10,    │     24,576 │ block_7_add[0][0] │
│ (Conv2D)            │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_8_expand_BN   │ (None, 10, 10,    │      1,536 │ block_8_expand[0… │
│ (BatchNormalizatio… │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_8_expand_relu │ (None, 10, 10,    │          0 │ block_8_expand_B… │
│ (ReLU)              │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_8_depthwise   │ (None, 10, 10,    │      3,456 │ block_8_expand_r… │
│ (DepthwiseConv2D)   │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_8_depthwise_… │ (None, 10, 10,    │      1,536 │ block_8_depthwis… │
│ (BatchNormalizatio… │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_8_depthwise_… │ (None, 10, 10,    │          0 │ block_8_depthwis… │
│ (ReLU)              │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_8_project     │ (None, 10, 10,    │     24,576 │ block_8_depthwis… │
│ (Conv2D)            │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_8_project_BN  │ (None, 10, 10,    │        256 │ block_8_project[… │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_8_add (Add)   │ (None, 10, 10,    │          0 │ block_7_add[0][0… │
│                     │ 64)               │            │ block_8_project_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_9_expand      │ (None, 10, 10,    │     24,576 │ block_8_add[0][0] │
│ (Conv2D)            │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_9_expand_BN   │ (None, 10, 10,    │      1,536 │ block_9_expand[0… │
│ (BatchNormalizatio… │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_9_expand_relu │ (None, 10, 10,    │          0 │ block_9_expand_B… │
│ (ReLU)              │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_9_depthwise   │ (None, 10, 10,    │      3,456 │ block_9_expand_r… │
│ (DepthwiseConv2D)   │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_9_depthwise_… │ (None, 10, 10,    │      1,536 │ block_9_depthwis… │
│ (BatchNormalizatio… │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_9_depthwise_… │ (None, 10, 10,    │          0 │ block_9_depthwis… │
│ (ReLU)              │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_9_project     │ (None, 10, 10,    │     24,576 │ block_9_depthwis… │
│ (Conv2D)            │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_9_project_BN  │ (None, 10, 10,    │        256 │ block_9_project[… │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_9_add (Add)   │ (None, 10, 10,    │          0 │ block_8_add[0][0… │
│                     │ 64)               │            │ block_9_project_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_10_expand     │ (None, 10, 10,    │     24,576 │ block_9_add[0][0] │
│ (Conv2D)            │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_10_expand_BN  │ (None, 10, 10,    │      1,536 │ block_10_expand[… │
│ (BatchNormalizatio… │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_10_expand_re… │ (None, 10, 10,    │          0 │ block_10_expand_… │
│ (ReLU)              │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_10_depthwise  │ (None, 10, 10,    │      3,456 │ block_10_expand_… │
│ (DepthwiseConv2D)   │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_10_depthwise… │ (None, 10, 10,    │      1,536 │ block_10_depthwi… │
│ (BatchNormalizatio… │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_10_depthwise… │ (None, 10, 10,    │          0 │ block_10_depthwi… │
│ (ReLU)              │ 384)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_10_project    │ (None, 10, 10,    │     36,864 │ block_10_depthwi… │
│ (Conv2D)            │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_10_project_BN │ (None, 10, 10,    │        384 │ block_10_project… │
│ (BatchNormalizatio… │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_11_expand     │ (None, 10, 10,    │     55,296 │ block_10_project… │
│ (Conv2D)            │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_11_expand_BN  │ (None, 10, 10,    │      2,304 │ block_11_expand[… │
│ (BatchNormalizatio… │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_11_expand_re… │ (None, 10, 10,    │          0 │ block_11_expand_… │
│ (ReLU)              │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_11_depthwise  │ (None, 10, 10,    │      5,184 │ block_11_expand_… │
│ (DepthwiseConv2D)   │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_11_depthwise… │ (None, 10, 10,    │      2,304 │ block_11_depthwi… │
│ (BatchNormalizatio… │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_11_depthwise… │ (None, 10, 10,    │          0 │ block_11_depthwi… │
│ (ReLU)              │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_11_project    │ (None, 10, 10,    │     55,296 │ block_11_depthwi… │
│ (Conv2D)            │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_11_project_BN │ (None, 10, 10,    │        384 │ block_11_project… │
│ (BatchNormalizatio… │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_11_add (Add)  │ (None, 10, 10,    │          0 │ block_10_project… │
│                     │ 96)               │            │ block_11_project… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_12_expand     │ (None, 10, 10,    │     55,296 │ block_11_add[0][… │
│ (Conv2D)            │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_12_expand_BN  │ (None, 10, 10,    │      2,304 │ block_12_expand[… │
│ (BatchNormalizatio… │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_12_expand_re… │ (None, 10, 10,    │          0 │ block_12_expand_… │
│ (ReLU)              │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_12_depthwise  │ (None, 10, 10,    │      5,184 │ block_12_expand_… │
│ (DepthwiseConv2D)   │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_12_depthwise… │ (None, 10, 10,    │      2,304 │ block_12_depthwi… │
│ (BatchNormalizatio… │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_12_depthwise… │ (None, 10, 10,    │          0 │ block_12_depthwi… │
│ (ReLU)              │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_12_project    │ (None, 10, 10,    │     55,296 │ block_12_depthwi… │
│ (Conv2D)            │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_12_project_BN │ (None, 10, 10,    │        384 │ block_12_project… │
│ (BatchNormalizatio… │ 96)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_12_add (Add)  │ (None, 10, 10,    │          0 │ block_11_add[0][… │
│                     │ 96)               │            │ block_12_project… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_13_expand     │ (None, 10, 10,    │     55,296 │ block_12_add[0][… │
│ (Conv2D)            │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_13_expand_BN  │ (None, 10, 10,    │      2,304 │ block_13_expand[… │
│ (BatchNormalizatio… │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_13_expand_re… │ (None, 10, 10,    │          0 │ block_13_expand_… │
│ (ReLU)              │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_13_pad        │ (None, 11, 11,    │          0 │ block_13_expand_… │
│ (ZeroPadding2D)     │ 576)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_13_depthwise  │ (None, 5, 5, 576) │      5,184 │ block_13_pad[0][… │
│ (DepthwiseConv2D)   │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_13_depthwise… │ (None, 5, 5, 576) │      2,304 │ block_13_depthwi… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_13_depthwise… │ (None, 5, 5, 576) │          0 │ block_13_depthwi… │
│ (ReLU)              │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_13_project    │ (None, 5, 5, 160) │     92,160 │ block_13_depthwi… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_13_project_BN │ (None, 5, 5, 160) │        640 │ block_13_project… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_14_expand     │ (None, 5, 5, 960) │    153,600 │ block_13_project… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_14_expand_BN  │ (None, 5, 5, 960) │      3,840 │ block_14_expand[… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_14_expand_re… │ (None, 5, 5, 960) │          0 │ block_14_expand_… │
│ (ReLU)              │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_14_depthwise  │ (None, 5, 5, 960) │      8,640 │ block_14_expand_… │
│ (DepthwiseConv2D)   │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_14_depthwise… │ (None, 5, 5, 960) │      3,840 │ block_14_depthwi… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_14_depthwise… │ (None, 5, 5, 960) │          0 │ block_14_depthwi… │
│ (ReLU)              │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_14_project    │ (None, 5, 5, 160) │    153,600 │ block_14_depthwi… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_14_project_BN │ (None, 5, 5, 160) │        640 │ block_14_project… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_14_add (Add)  │ (None, 5, 5, 160) │          0 │ block_13_project… │
│                     │                   │            │ block_14_project… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_15_expand     │ (None, 5, 5, 960) │    153,600 │ block_14_add[0][… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_15_expand_BN  │ (None, 5, 5, 960) │      3,840 │ block_15_expand[… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_15_expand_re… │ (None, 5, 5, 960) │          0 │ block_15_expand_… │
│ (ReLU)              │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_15_depthwise  │ (None, 5, 5, 960) │      8,640 │ block_15_expand_… │
│ (DepthwiseConv2D)   │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_15_depthwise… │ (None, 5, 5, 960) │      3,840 │ block_15_depthwi… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_15_depthwise… │ (None, 5, 5, 960) │          0 │ block_15_depthwi… │
│ (ReLU)              │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_15_project    │ (None, 5, 5, 160) │    153,600 │ block_15_depthwi… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_15_project_BN │ (None, 5, 5, 160) │        640 │ block_15_project… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_15_add (Add)  │ (None, 5, 5, 160) │          0 │ block_14_add[0][… │
│                     │                   │            │ block_15_project… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_16_expand     │ (None, 5, 5, 960) │    153,600 │ block_15_add[0][… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_16_expand_BN  │ (None, 5, 5, 960) │      3,840 │ block_16_expand[… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_16_expand_re… │ (None, 5, 5, 960) │          0 │ block_16_expand_… │
│ (ReLU)              │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_16_depthwise  │ (None, 5, 5, 960) │      8,640 │ block_16_expand_… │
│ (DepthwiseConv2D)   │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_16_depthwise… │ (None, 5, 5, 960) │      3,840 │ block_16_depthwi… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_16_depthwise… │ (None, 5, 5, 960) │          0 │ block_16_depthwi… │
│ (ReLU)              │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_16_project    │ (None, 5, 5, 320) │    307,200 │ block_16_depthwi… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ block_16_project_BN │ (None, 5, 5, 320) │      1,280 │ block_16_project… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ Conv_1 (Conv2D)     │ (None, 5, 5,      │    409,600 │ block_16_project… │
│                     │ 1280)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ Conv_1_bn           │ (None, 5, 5,      │      5,120 │ Conv_1[0][0]      │
│ (BatchNormalizatio… │ 1280)             │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ out_relu (ReLU)     │ (None, 5, 5,      │          0 │ Conv_1_bn[0][0]   │
│                     │ 1280)             │            │                   │
└─────────────────────┴───────────────────┴────────────┴───────────────────┘
 Total params: 2,257,984 (8.61 MB)
 Trainable params: 0 (0.00 B)
 Non-trainable params: 2,257,984 (8.61 MB)
MobileNetV3 Architecture
Model: "MobilenetV3large"
┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━┓
┃ Layer (type)        ┃ Output Shape      ┃    Param # ┃ Connected to      ┃
┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━┩
│ input_layer_38      │ (None, 160, 160,  │          0 │ -                 │
│ (InputLayer)        │ 3)                │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ rescaling_9         │ (None, 160, 160,  │          0 │ input_layer_38[0… │
│ (Rescaling)         │ 3)                │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv (Conv2D)       │ (None, 80, 80,    │        432 │ rescaling_9[0][0] │
│                     │ 16)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv_bn             │ (None, 80, 80,    │         64 │ conv[0][0]        │
│ (BatchNormalizatio… │ 16)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_100      │ (None, 80, 80,    │          0 │ conv_bn[0][0]     │
│ (Activation)        │ 16)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_dept… │ (None, 80, 80,    │        144 │ activation_100[0… │
│ (DepthwiseConv2D)   │ 16)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_dept… │ (None, 80, 80,    │         64 │ expanded_conv_de… │
│ (BatchNormalizatio… │ 16)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_95 (ReLU)     │ (None, 80, 80,    │          0 │ expanded_conv_de… │
│                     │ 16)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_proj… │ (None, 80, 80,    │        256 │ re_lu_95[0][0]    │
│ (Conv2D)            │ 16)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_proj… │ (None, 80, 80,    │         64 │ expanded_conv_pr… │
│ (BatchNormalizatio… │ 16)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_add   │ (None, 80, 80,    │          0 │ activation_100[0… │
│ (Add)               │ 16)               │            │ expanded_conv_pr… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_1_ex… │ (None, 80, 80,    │      1,024 │ expanded_conv_ad… │
│ (Conv2D)            │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_1_ex… │ (None, 80, 80,    │        256 │ expanded_conv_1_… │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_96 (ReLU)     │ (None, 80, 80,    │          0 │ expanded_conv_1_… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_1_de… │ (None, 81, 81,    │          0 │ re_lu_96[0][0]    │
│ (ZeroPadding2D)     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_1_de… │ (None, 40, 40,    │        576 │ expanded_conv_1_… │
│ (DepthwiseConv2D)   │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_1_de… │ (None, 40, 40,    │        256 │ expanded_conv_1_… │
│ (BatchNormalizatio… │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_97 (ReLU)     │ (None, 40, 40,    │          0 │ expanded_conv_1_… │
│                     │ 64)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_1_pr… │ (None, 40, 40,    │      1,536 │ re_lu_97[0][0]    │
│ (Conv2D)            │ 24)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_1_pr… │ (None, 40, 40,    │         96 │ expanded_conv_1_… │
│ (BatchNormalizatio… │ 24)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_2_ex… │ (None, 40, 40,    │      1,728 │ expanded_conv_1_… │
│ (Conv2D)            │ 72)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_2_ex… │ (None, 40, 40,    │        288 │ expanded_conv_2_… │
│ (BatchNormalizatio… │ 72)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_98 (ReLU)     │ (None, 40, 40,    │          0 │ expanded_conv_2_… │
│                     │ 72)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_2_de… │ (None, 40, 40,    │        648 │ re_lu_98[0][0]    │
│ (DepthwiseConv2D)   │ 72)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_2_de… │ (None, 40, 40,    │        288 │ expanded_conv_2_… │
│ (BatchNormalizatio… │ 72)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_99 (ReLU)     │ (None, 40, 40,    │          0 │ expanded_conv_2_… │
│                     │ 72)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_2_pr… │ (None, 40, 40,    │      1,728 │ re_lu_99[0][0]    │
│ (Conv2D)            │ 24)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_2_pr… │ (None, 40, 40,    │         96 │ expanded_conv_2_… │
│ (BatchNormalizatio… │ 24)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_2_add │ (None, 40, 40,    │          0 │ expanded_conv_1_… │
│ (Add)               │ 24)               │            │ expanded_conv_2_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_3_ex… │ (None, 40, 40,    │      1,728 │ expanded_conv_2_… │
│ (Conv2D)            │ 72)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_3_ex… │ (None, 40, 40,    │        288 │ expanded_conv_3_… │
│ (BatchNormalizatio… │ 72)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_100 (ReLU)    │ (None, 40, 40,    │          0 │ expanded_conv_3_… │
│                     │ 72)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_3_de… │ (None, 43, 43,    │          0 │ re_lu_100[0][0]   │
│ (ZeroPadding2D)     │ 72)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_3_de… │ (None, 20, 20,    │      1,800 │ expanded_conv_3_… │
│ (DepthwiseConv2D)   │ 72)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_3_de… │ (None, 20, 20,    │        288 │ expanded_conv_3_… │
│ (BatchNormalizatio… │ 72)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_101 (ReLU)    │ (None, 20, 20,    │          0 │ expanded_conv_3_… │
│                     │ 72)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_3_sq… │ (None, 1, 1, 72)  │          0 │ re_lu_101[0][0]   │
│ (GlobalAveragePool… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_3_sq… │ (None, 1, 1, 24)  │      1,752 │ expanded_conv_3_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_3_sq… │ (None, 1, 1, 24)  │          0 │ expanded_conv_3_… │
│ (ReLU)              │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_3_sq… │ (None, 1, 1, 72)  │      1,800 │ expanded_conv_3_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ add_76 (Add)        │ (None, 1, 1, 72)  │          0 │ expanded_conv_3_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_102 (ReLU)    │ (None, 1, 1, 72)  │          0 │ add_76[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ multiply_40         │ (None, 1, 1, 72)  │          0 │ re_lu_102[0][0]   │
│ (Multiply)          │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_3_sq… │ (None, 20, 20,    │          0 │ re_lu_101[0][0],  │
│ (Multiply)          │ 72)               │            │ multiply_40[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_3_pr… │ (None, 20, 20,    │      2,880 │ expanded_conv_3_… │
│ (Conv2D)            │ 40)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_3_pr… │ (None, 20, 20,    │        160 │ expanded_conv_3_… │
│ (BatchNormalizatio… │ 40)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_4_ex… │ (None, 20, 20,    │      4,800 │ expanded_conv_3_… │
│ (Conv2D)            │ 120)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_4_ex… │ (None, 20, 20,    │        480 │ expanded_conv_4_… │
│ (BatchNormalizatio… │ 120)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_103 (ReLU)    │ (None, 20, 20,    │          0 │ expanded_conv_4_… │
│                     │ 120)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_4_de… │ (None, 20, 20,    │      3,000 │ re_lu_103[0][0]   │
│ (DepthwiseConv2D)   │ 120)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_4_de… │ (None, 20, 20,    │        480 │ expanded_conv_4_… │
│ (BatchNormalizatio… │ 120)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_104 (ReLU)    │ (None, 20, 20,    │          0 │ expanded_conv_4_… │
│                     │ 120)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_4_sq… │ (None, 1, 1, 120) │          0 │ re_lu_104[0][0]   │
│ (GlobalAveragePool… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_4_sq… │ (None, 1, 1, 32)  │      3,872 │ expanded_conv_4_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_4_sq… │ (None, 1, 1, 32)  │          0 │ expanded_conv_4_… │
│ (ReLU)              │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_4_sq… │ (None, 1, 1, 120) │      3,960 │ expanded_conv_4_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ add_77 (Add)        │ (None, 1, 1, 120) │          0 │ expanded_conv_4_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_105 (ReLU)    │ (None, 1, 1, 120) │          0 │ add_77[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ multiply_41         │ (None, 1, 1, 120) │          0 │ re_lu_105[0][0]   │
│ (Multiply)          │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_4_sq… │ (None, 20, 20,    │          0 │ re_lu_104[0][0],  │
│ (Multiply)          │ 120)              │            │ multiply_41[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_4_pr… │ (None, 20, 20,    │      4,800 │ expanded_conv_4_… │
│ (Conv2D)            │ 40)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_4_pr… │ (None, 20, 20,    │        160 │ expanded_conv_4_… │
│ (BatchNormalizatio… │ 40)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_4_add │ (None, 20, 20,    │          0 │ expanded_conv_3_… │
│ (Add)               │ 40)               │            │ expanded_conv_4_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_5_ex… │ (None, 20, 20,    │      4,800 │ expanded_conv_4_… │
│ (Conv2D)            │ 120)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_5_ex… │ (None, 20, 20,    │        480 │ expanded_conv_5_… │
│ (BatchNormalizatio… │ 120)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_106 (ReLU)    │ (None, 20, 20,    │          0 │ expanded_conv_5_… │
│                     │ 120)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_5_de… │ (None, 20, 20,    │      3,000 │ re_lu_106[0][0]   │
│ (DepthwiseConv2D)   │ 120)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_5_de… │ (None, 20, 20,    │        480 │ expanded_conv_5_… │
│ (BatchNormalizatio… │ 120)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_107 (ReLU)    │ (None, 20, 20,    │          0 │ expanded_conv_5_… │
│                     │ 120)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_5_sq… │ (None, 1, 1, 120) │          0 │ re_lu_107[0][0]   │
│ (GlobalAveragePool… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_5_sq… │ (None, 1, 1, 32)  │      3,872 │ expanded_conv_5_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_5_sq… │ (None, 1, 1, 32)  │          0 │ expanded_conv_5_… │
│ (ReLU)              │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_5_sq… │ (None, 1, 1, 120) │      3,960 │ expanded_conv_5_… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ add_78 (Add)        │ (None, 1, 1, 120) │          0 │ expanded_conv_5_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_108 (ReLU)    │ (None, 1, 1, 120) │          0 │ add_78[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ multiply_42         │ (None, 1, 1, 120) │          0 │ re_lu_108[0][0]   │
│ (Multiply)          │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_5_sq… │ (None, 20, 20,    │          0 │ re_lu_107[0][0],  │
│ (Multiply)          │ 120)              │            │ multiply_42[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_5_pr… │ (None, 20, 20,    │      4,800 │ expanded_conv_5_… │
│ (Conv2D)            │ 40)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_5_pr… │ (None, 20, 20,    │        160 │ expanded_conv_5_… │
│ (BatchNormalizatio… │ 40)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_5_add │ (None, 20, 20,    │          0 │ expanded_conv_4_… │
│ (Add)               │ 40)               │            │ expanded_conv_5_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_6_ex… │ (None, 20, 20,    │      9,600 │ expanded_conv_5_… │
│ (Conv2D)            │ 240)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_6_ex… │ (None, 20, 20,    │        960 │ expanded_conv_6_… │
│ (BatchNormalizatio… │ 240)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_101      │ (None, 20, 20,    │          0 │ expanded_conv_6_… │
│ (Activation)        │ 240)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_6_de… │ (None, 21, 21,    │          0 │ activation_101[0… │
│ (ZeroPadding2D)     │ 240)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_6_de… │ (None, 10, 10,    │      2,160 │ expanded_conv_6_… │
│ (DepthwiseConv2D)   │ 240)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_6_de… │ (None, 10, 10,    │        960 │ expanded_conv_6_… │
│ (BatchNormalizatio… │ 240)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_102      │ (None, 10, 10,    │          0 │ expanded_conv_6_… │
│ (Activation)        │ 240)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_6_pr… │ (None, 10, 10,    │     19,200 │ activation_102[0… │
│ (Conv2D)            │ 80)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_6_pr… │ (None, 10, 10,    │        320 │ expanded_conv_6_… │
│ (BatchNormalizatio… │ 80)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_7_ex… │ (None, 10, 10,    │     16,000 │ expanded_conv_6_… │
│ (Conv2D)            │ 200)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_7_ex… │ (None, 10, 10,    │        800 │ expanded_conv_7_… │
│ (BatchNormalizatio… │ 200)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_103      │ (None, 10, 10,    │          0 │ expanded_conv_7_… │
│ (Activation)        │ 200)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_7_de… │ (None, 10, 10,    │      1,800 │ activation_103[0… │
│ (DepthwiseConv2D)   │ 200)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_7_de… │ (None, 10, 10,    │        800 │ expanded_conv_7_… │
│ (BatchNormalizatio… │ 200)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_104      │ (None, 10, 10,    │          0 │ expanded_conv_7_… │
│ (Activation)        │ 200)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_7_pr… │ (None, 10, 10,    │     16,000 │ activation_104[0… │
│ (Conv2D)            │ 80)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_7_pr… │ (None, 10, 10,    │        320 │ expanded_conv_7_… │
│ (BatchNormalizatio… │ 80)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_7_add │ (None, 10, 10,    │          0 │ expanded_conv_6_… │
│ (Add)               │ 80)               │            │ expanded_conv_7_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_8_ex… │ (None, 10, 10,    │     14,720 │ expanded_conv_7_… │
│ (Conv2D)            │ 184)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_8_ex… │ (None, 10, 10,    │        736 │ expanded_conv_8_… │
│ (BatchNormalizatio… │ 184)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_105      │ (None, 10, 10,    │          0 │ expanded_conv_8_… │
│ (Activation)        │ 184)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_8_de… │ (None, 10, 10,    │      1,656 │ activation_105[0… │
│ (DepthwiseConv2D)   │ 184)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_8_de… │ (None, 10, 10,    │        736 │ expanded_conv_8_… │
│ (BatchNormalizatio… │ 184)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_106      │ (None, 10, 10,    │          0 │ expanded_conv_8_… │
│ (Activation)        │ 184)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_8_pr… │ (None, 10, 10,    │     14,720 │ activation_106[0… │
│ (Conv2D)            │ 80)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_8_pr… │ (None, 10, 10,    │        320 │ expanded_conv_8_… │
│ (BatchNormalizatio… │ 80)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_8_add │ (None, 10, 10,    │          0 │ expanded_conv_7_… │
│ (Add)               │ 80)               │            │ expanded_conv_8_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_9_ex… │ (None, 10, 10,    │     14,720 │ expanded_conv_8_… │
│ (Conv2D)            │ 184)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_9_ex… │ (None, 10, 10,    │        736 │ expanded_conv_9_… │
│ (BatchNormalizatio… │ 184)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_107      │ (None, 10, 10,    │          0 │ expanded_conv_9_… │
│ (Activation)        │ 184)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_9_de… │ (None, 10, 10,    │      1,656 │ activation_107[0… │
│ (DepthwiseConv2D)   │ 184)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_9_de… │ (None, 10, 10,    │        736 │ expanded_conv_9_… │
│ (BatchNormalizatio… │ 184)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_108      │ (None, 10, 10,    │          0 │ expanded_conv_9_… │
│ (Activation)        │ 184)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_9_pr… │ (None, 10, 10,    │     14,720 │ activation_108[0… │
│ (Conv2D)            │ 80)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_9_pr… │ (None, 10, 10,    │        320 │ expanded_conv_9_… │
│ (BatchNormalizatio… │ 80)               │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_9_add │ (None, 10, 10,    │          0 │ expanded_conv_8_… │
│ (Add)               │ 80)               │            │ expanded_conv_9_… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_10_e… │ (None, 10, 10,    │     38,400 │ expanded_conv_9_… │
│ (Conv2D)            │ 480)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_10_e… │ (None, 10, 10,    │      1,920 │ expanded_conv_10… │
│ (BatchNormalizatio… │ 480)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_109      │ (None, 10, 10,    │          0 │ expanded_conv_10… │
│ (Activation)        │ 480)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_10_d… │ (None, 10, 10,    │      4,320 │ activation_109[0… │
│ (DepthwiseConv2D)   │ 480)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_10_d… │ (None, 10, 10,    │      1,920 │ expanded_conv_10… │
│ (BatchNormalizatio… │ 480)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_110      │ (None, 10, 10,    │          0 │ expanded_conv_10… │
│ (Activation)        │ 480)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_10_s… │ (None, 1, 1, 480) │          0 │ activation_110[0… │
│ (GlobalAveragePool… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_10_s… │ (None, 1, 1, 120) │     57,720 │ expanded_conv_10… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_10_s… │ (None, 1, 1, 120) │          0 │ expanded_conv_10… │
│ (ReLU)              │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_10_s… │ (None, 1, 1, 480) │     58,080 │ expanded_conv_10… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ add_79 (Add)        │ (None, 1, 1, 480) │          0 │ expanded_conv_10… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_109 (ReLU)    │ (None, 1, 1, 480) │          0 │ add_79[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ multiply_43         │ (None, 1, 1, 480) │          0 │ re_lu_109[0][0]   │
│ (Multiply)          │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_10_s… │ (None, 10, 10,    │          0 │ activation_110[0… │
│ (Multiply)          │ 480)              │            │ multiply_43[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_10_p… │ (None, 10, 10,    │     53,760 │ expanded_conv_10… │
│ (Conv2D)            │ 112)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_10_p… │ (None, 10, 10,    │        448 │ expanded_conv_10… │
│ (BatchNormalizatio… │ 112)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_11_e… │ (None, 10, 10,    │     75,264 │ expanded_conv_10… │
│ (Conv2D)            │ 672)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_11_e… │ (None, 10, 10,    │      2,688 │ expanded_conv_11… │
│ (BatchNormalizatio… │ 672)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_111      │ (None, 10, 10,    │          0 │ expanded_conv_11… │
│ (Activation)        │ 672)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_11_d… │ (None, 10, 10,    │      6,048 │ activation_111[0… │
│ (DepthwiseConv2D)   │ 672)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_11_d… │ (None, 10, 10,    │      2,688 │ expanded_conv_11… │
│ (BatchNormalizatio… │ 672)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_112      │ (None, 10, 10,    │          0 │ expanded_conv_11… │
│ (Activation)        │ 672)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_11_s… │ (None, 1, 1, 672) │          0 │ activation_112[0… │
│ (GlobalAveragePool… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_11_s… │ (None, 1, 1, 168) │    113,064 │ expanded_conv_11… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_11_s… │ (None, 1, 1, 168) │          0 │ expanded_conv_11… │
│ (ReLU)              │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_11_s… │ (None, 1, 1, 672) │    113,568 │ expanded_conv_11… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ add_80 (Add)        │ (None, 1, 1, 672) │          0 │ expanded_conv_11… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_110 (ReLU)    │ (None, 1, 1, 672) │          0 │ add_80[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ multiply_44         │ (None, 1, 1, 672) │          0 │ re_lu_110[0][0]   │
│ (Multiply)          │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_11_s… │ (None, 10, 10,    │          0 │ activation_112[0… │
│ (Multiply)          │ 672)              │            │ multiply_44[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_11_p… │ (None, 10, 10,    │     75,264 │ expanded_conv_11… │
│ (Conv2D)            │ 112)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_11_p… │ (None, 10, 10,    │        448 │ expanded_conv_11… │
│ (BatchNormalizatio… │ 112)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_11_a… │ (None, 10, 10,    │          0 │ expanded_conv_10… │
│ (Add)               │ 112)              │            │ expanded_conv_11… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_12_e… │ (None, 10, 10,    │     75,264 │ expanded_conv_11… │
│ (Conv2D)            │ 672)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_12_e… │ (None, 10, 10,    │      2,688 │ expanded_conv_12… │
│ (BatchNormalizatio… │ 672)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_113      │ (None, 10, 10,    │          0 │ expanded_conv_12… │
│ (Activation)        │ 672)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_12_d… │ (None, 13, 13,    │          0 │ activation_113[0… │
│ (ZeroPadding2D)     │ 672)              │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_12_d… │ (None, 5, 5, 672) │     16,800 │ expanded_conv_12… │
│ (DepthwiseConv2D)   │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_12_d… │ (None, 5, 5, 672) │      2,688 │ expanded_conv_12… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_114      │ (None, 5, 5, 672) │          0 │ expanded_conv_12… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_12_s… │ (None, 1, 1, 672) │          0 │ activation_114[0… │
│ (GlobalAveragePool… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_12_s… │ (None, 1, 1, 168) │    113,064 │ expanded_conv_12… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_12_s… │ (None, 1, 1, 168) │          0 │ expanded_conv_12… │
│ (ReLU)              │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_12_s… │ (None, 1, 1, 672) │    113,568 │ expanded_conv_12… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ add_81 (Add)        │ (None, 1, 1, 672) │          0 │ expanded_conv_12… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_111 (ReLU)    │ (None, 1, 1, 672) │          0 │ add_81[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ multiply_45         │ (None, 1, 1, 672) │          0 │ re_lu_111[0][0]   │
│ (Multiply)          │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_12_s… │ (None, 5, 5, 672) │          0 │ activation_114[0… │
│ (Multiply)          │                   │            │ multiply_45[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_12_p… │ (None, 5, 5, 160) │    107,520 │ expanded_conv_12… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_12_p… │ (None, 5, 5, 160) │        640 │ expanded_conv_12… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_13_e… │ (None, 5, 5, 960) │    153,600 │ expanded_conv_12… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_13_e… │ (None, 5, 5, 960) │      3,840 │ expanded_conv_13… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_115      │ (None, 5, 5, 960) │          0 │ expanded_conv_13… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_13_d… │ (None, 5, 5, 960) │     24,000 │ activation_115[0… │
│ (DepthwiseConv2D)   │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_13_d… │ (None, 5, 5, 960) │      3,840 │ expanded_conv_13… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_116      │ (None, 5, 5, 960) │          0 │ expanded_conv_13… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_13_s… │ (None, 1, 1, 960) │          0 │ activation_116[0… │
│ (GlobalAveragePool… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_13_s… │ (None, 1, 1, 240) │    230,640 │ expanded_conv_13… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_13_s… │ (None, 1, 1, 240) │          0 │ expanded_conv_13… │
│ (ReLU)              │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_13_s… │ (None, 1, 1, 960) │    231,360 │ expanded_conv_13… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ add_82 (Add)        │ (None, 1, 1, 960) │          0 │ expanded_conv_13… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_112 (ReLU)    │ (None, 1, 1, 960) │          0 │ add_82[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ multiply_46         │ (None, 1, 1, 960) │          0 │ re_lu_112[0][0]   │
│ (Multiply)          │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_13_s… │ (None, 5, 5, 960) │          0 │ activation_116[0… │
│ (Multiply)          │                   │            │ multiply_46[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_13_p… │ (None, 5, 5, 160) │    153,600 │ expanded_conv_13… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_13_p… │ (None, 5, 5, 160) │        640 │ expanded_conv_13… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_13_a… │ (None, 5, 5, 160) │          0 │ expanded_conv_12… │
│ (Add)               │                   │            │ expanded_conv_13… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_14_e… │ (None, 5, 5, 960) │    153,600 │ expanded_conv_13… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_14_e… │ (None, 5, 5, 960) │      3,840 │ expanded_conv_14… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_117      │ (None, 5, 5, 960) │          0 │ expanded_conv_14… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_14_d… │ (None, 5, 5, 960) │     24,000 │ activation_117[0… │
│ (DepthwiseConv2D)   │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_14_d… │ (None, 5, 5, 960) │      3,840 │ expanded_conv_14… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_118      │ (None, 5, 5, 960) │          0 │ expanded_conv_14… │
│ (Activation)        │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_14_s… │ (None, 1, 1, 960) │          0 │ activation_118[0… │
│ (GlobalAveragePool… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_14_s… │ (None, 1, 1, 240) │    230,640 │ expanded_conv_14… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_14_s… │ (None, 1, 1, 240) │          0 │ expanded_conv_14… │
│ (ReLU)              │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_14_s… │ (None, 1, 1, 960) │    231,360 │ expanded_conv_14… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ add_83 (Add)        │ (None, 1, 1, 960) │          0 │ expanded_conv_14… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ re_lu_113 (ReLU)    │ (None, 1, 1, 960) │          0 │ add_83[0][0]      │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ multiply_47         │ (None, 1, 1, 960) │          0 │ re_lu_113[0][0]   │
│ (Multiply)          │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_14_s… │ (None, 5, 5, 960) │          0 │ activation_118[0… │
│ (Multiply)          │                   │            │ multiply_47[0][0] │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_14_p… │ (None, 5, 5, 160) │    153,600 │ expanded_conv_14… │
│ (Conv2D)            │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_14_p… │ (None, 5, 5, 160) │        640 │ expanded_conv_14… │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ expanded_conv_14_a… │ (None, 5, 5, 160) │          0 │ expanded_conv_13… │
│ (Add)               │                   │            │ expanded_conv_14… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv_1 (Conv2D)     │ (None, 5, 5, 960) │    153,600 │ expanded_conv_14… │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ conv_1_bn           │ (None, 5, 5, 960) │      3,840 │ conv_1[0][0]      │
│ (BatchNormalizatio… │                   │            │                   │
├─────────────────────┼───────────────────┼────────────┼───────────────────┤
│ activation_119      │ (None, 5, 5, 960) │          0 │ conv_1_bn[0][0]   │
│ (Activation)        │                   │            │                   │
└─────────────────────┴───────────────────┴────────────┴───────────────────┘
 Total params: 2,996,352 (11.43 MB)
 Trainable params: 0 (0.00 B)
 Non-trainable params: 2,996,352 (11.43 MB)

Add a classification head¶

To generate predictions from the block of features, average over the spatial 5x5 spatial locations, using a tf.keras.layers.GlobalAveragePooling2D layer to convert the features to a single 1280-element vector per image.

In [ ]:
global_average_layer_v1 = tf.keras.layers.GlobalAveragePooling2D()
global_average_layer_v2 = tf.keras.layers.GlobalAveragePooling2D()  
global_average_layer_v3 = tf.keras.layers.GlobalAveragePooling2D()

feature_batch_average_v1 = global_average_layer_v1(feature_batch_v1)  
feature_batch_average_v2 = global_average_layer_v2(feature_batch_v2)
feature_batch_average_v3 = global_average_layer_v3(feature_batch_v3)


print("MobileNet Feature Batch Average Shape:", feature_batch_average_v1.shape)
print("MobileNetV2 Feature Batch Average Shape:", feature_batch_average_v2.shape)
print("MobileNetV3 Feature Batch Average Shape:", feature_batch_average_v3.shape)
MobileNet Feature Batch Average Shape: (32, 1024)
MobileNetV2 Feature Batch Average Shape: (32, 1280)
MobileNetV3 Feature Batch Average Shape: (32, 960)

Apply a tf.keras.layers.Dense layer to convert these features into a single prediction per image. You don't need an activation function here because this prediction will be treated as a logit, or a raw prediction value. Positive numbers predict class 1, negative numbers predict class 0.

In [ ]:
# Define separate prediction layers for each model version to avoid shape incompatibility
prediction_layer_v1 = tf.keras.layers.Dense(1, activation='sigmoid')
prediction_layer_v2 = tf.keras.layers.Dense(1, activation='sigmoid')
prediction_layer_v3 = tf.keras.layers.Dense(1, activation='sigmoid')

prediction_batch_v1 = prediction_layer_v1(feature_batch_average_v1)
prediction_batch_v2 = prediction_layer_v2(feature_batch_average_v2)
prediction_batch_v3 = prediction_layer_v3(feature_batch_average_v3)

print("MobileNet Prediction Batch Shape:", prediction_batch_v1.shape)
print("MobileNetV2 Prediction Batch Shape:", prediction_batch_v2.shape)
print("MobileNetV3 Prediction Batch Shape:", prediction_batch_v3.shape)
MobileNet Prediction Batch Shape: (32, 1)
MobileNetV2 Prediction Batch Shape: (32, 1)
MobileNetV3 Prediction Batch Shape: (32, 1)

Build a model by chaining together the data augmentation, rescaling, base_model and feature extractor layers using the Keras Functional API. As previously mentioned, use training=False as our model contains a BatchNormalization layer.

In [ ]:
inputs = tf.keras.Input(shape=(160, 160, 3))

# MobileNet
x_v1 = data_augmentation(inputs)
x_v1 = preprocess_input_v1(x_v1)
x_v1 = base_model_v1(x_v1, training=False)
x_v1 = global_average_layer_v1(x_v1)
x_v1 = tf.keras.layers.Dropout(0.2)(x_v1)
outputs_v1 = prediction_layer_v1(x_v1)
model_v1 = tf.keras.Model(inputs, outputs_v1)

# MobileNet V2
x_v2 = data_augmentation(inputs)
x_v2 = preprocess_input_v2(x_v2)
x_v2 = base_model_v2(x_v2, training=False)
x_v2 = global_average_layer_v2(x_v2)
x_v2 = tf.keras.layers.Dropout(0.2)(x_v2)
outputs_v2 = prediction_layer_v2(x_v2)
model_v2 = tf.keras.Model(inputs, outputs_v2)

# MobileNet V3
x_v3 = data_augmentation(inputs)
x_v3 = preprocess_input_v3(x_v3)
x_v3 = base_model_v3(x_v3, training=False)
x_v3 = global_average_layer_v3(x_v3)
x_v3 = tf.keras.layers.Dropout(0.2)(x_v3)
outputs_v3 = prediction_layer_v3(x_v3)
model_v3 = tf.keras.Model(inputs, outputs_v3)
In [ ]:
print("\nMobileNet Model Summary")
model_v1.summary()

print("MobileNet V2 Model Summary")
model_v2.summary()

print("MobileNet V3 Model Summary")
model_v3.summary()
MobileNet Model Summary
Model: "functional_57"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type)                    ┃ Output Shape           ┃       Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ input_layer_39 (InputLayer)     │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ sequential_5 (Sequential)       │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ true_divide_16 (TrueDivide)     │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ subtract_16 (Subtract)          │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ mobilenet_1.00_160 (Functional) │ (None, 5, 5, 1024)     │     3,228,864 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ global_average_pooling2d_11     │ (None, 1024)           │             0 │
│ (GlobalAveragePooling2D)        │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_28 (Dropout)            │ (None, 1024)           │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_19 (Dense)                │ (None, 1)              │         1,025 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
 Total params: 3,229,889 (12.32 MB)
 Trainable params: 1,025 (4.00 KB)
 Non-trainable params: 3,228,864 (12.32 MB)
MobileNet V2 Model Summary
Model: "functional_59"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type)                    ┃ Output Shape           ┃       Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ input_layer_39 (InputLayer)     │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ sequential_5 (Sequential)       │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ true_divide_17 (TrueDivide)     │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ subtract_17 (Subtract)          │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ mobilenetv2_1.00_160            │ (None, 5, 5, 1280)     │     2,257,984 │
│ (Functional)                    │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ global_average_pooling2d_12     │ (None, 1280)           │             0 │
│ (GlobalAveragePooling2D)        │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_29 (Dropout)            │ (None, 1280)           │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_20 (Dense)                │ (None, 1)              │         1,281 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
 Total params: 2,259,265 (8.62 MB)
 Trainable params: 1,281 (5.00 KB)
 Non-trainable params: 2,257,984 (8.61 MB)
MobileNet V3 Model Summary
Model: "functional_61"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type)                    ┃ Output Shape           ┃       Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ input_layer_39 (InputLayer)     │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ sequential_5 (Sequential)       │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ MobilenetV3large (Functional)   │ (None, 5, 5, 960)      │     2,996,352 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ global_average_pooling2d_13     │ (None, 960)            │             0 │
│ (GlobalAveragePooling2D)        │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_30 (Dropout)            │ (None, 960)            │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_21 (Dense)                │ (None, 1)              │           961 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
 Total params: 2,997,313 (11.43 MB)
 Trainable params: 961 (3.75 KB)
 Non-trainable params: 2,996,352 (11.43 MB)

The 8+ million parameters in MobileNet are frozen, but there are 1.2 thousand trainable parameters in the Dense layer. These are divided between two tf.Variable objects, the weights and biases.

In [ ]:
# The trainable parameters in MobileNet
print("MobileNet Trainable Parameters:", len(model_v1.trainable_variables))

# The trainable parameters in MobileNet V2
print("\nMobileNet V2 Trainable Parameters:", len(model_v2.trainable_variables))

# The trainable parameters in MobileNet V3
print("MobileNet V3 Trainable Parameters:", len(model_v3.trainable_variables))
MobileNet Trainable Parameters: 2

MobileNet V2 Trainable Parameters: 2
MobileNet V3 Trainable Parameters: 2
In [ ]:
# Plot model for MobileNet
print("\nMobileNet Plot Model")
tf.keras.utils.plot_model(model_v1, show_shapes=True)
MobileNet Plot Model
Out[ ]:
In [ ]:
# Plot model for MobileNet V2
print("\nMobileNet V2 Plot Model")
tf.keras.utils.plot_model(model_v2, show_shapes=True)
MobileNet V2 Plot Model
Out[ ]:
In [ ]:
# plot model for MobileNet V3
print("\nMobileNet V3 Plot Model")
tf.keras.utils.plot_model(model_v3, show_shapes=True)
MobileNet V3 Plot Model
Out[ ]:

Compile the model¶

Compile the model before training it. Since there are two classes and a sigmoid oputput, use the BinaryAccuracy.

In [ ]:
base_learning_rate = 0.0001

model_v1.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=base_learning_rate),
                    loss=tf.keras.losses.BinaryCrossentropy(),
                    metrics=[tf.keras.metrics.BinaryAccuracy(threshold=0.5, name='accuracy')])

model_v2.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=base_learning_rate),
                 loss=tf.keras.losses.BinaryCrossentropy(),
                 metrics=[tf.keras.metrics.BinaryAccuracy(threshold=0.5, name='accuracy')])

model_v3.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=base_learning_rate),
                    loss=tf.keras.losses.BinaryCrossentropy(),
                    metrics=[tf.keras.metrics.BinaryAccuracy(threshold=0.5, name='accuracy')])

Train the model¶

After training for 10 epochs, you should see ~96% accuracy on the validation set.

In [ ]:
initial_epochs = 10

loss0_v1, accuracy0_v1 = model_v1.evaluate(validation_dataset)
loss0_v2, accuracy0_v2 = model_v2.evaluate(validation_dataset)
loss0_v3, accuracy0_v3 = model_v3.evaluate(validation_dataset)
26/26 ━━━━━━━━━━━━━━━━━━━━ 8s 270ms/step - accuracy: 0.5010 - loss: 0.8441
26/26 ━━━━━━━━━━━━━━━━━━━━ 8s 269ms/step - accuracy: 0.7358 - loss: 0.5630
26/26 ━━━━━━━━━━━━━━━━━━━━ 7s 198ms/step - accuracy: 0.3535 - loss: 1.2245
In [ ]:
print("MobileNet V1 initial loss: {:.2f}".format(loss0_v1))
print("MobileNet V1 initial accuracy: {:.2f}".format(accuracy0_v1))

print("MobileNet V2 initial loss: {:.2f}".format(loss0_v2))
print("MobileNet V2 initial accuracy: {:.2f}".format(accuracy0_v2))

print("MobileNet V3 initial loss: {:.2f}".format(loss0_v3))
print("MobileNet V3 initial accuracy: {:.2f}".format(accuracy0_v3))
MobileNet V1 initial loss: 0.85
MobileNet V1 initial accuracy: 0.51
MobileNet V2 initial loss: 0.58
MobileNet V2 initial accuracy: 0.70
MobileNet V3 initial loss: 1.25
MobileNet V3 initial accuracy: 0.33
In [ ]:
history_v1 = model_v1.fit(train_dataset,
                            epochs=initial_epochs,
                            validation_data=validation_dataset)

history_v2 = model_v2.fit(train_dataset,
                          epochs=initial_epochs,
                          validation_data=validation_dataset)

history_v3 = model_v3.fit(train_dataset,
                            epochs=initial_epochs,
                            validation_data=validation_dataset)
Epoch 1/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 25s 351ms/step - accuracy: 0.5531 - loss: 0.8277 - val_accuracy: 0.6869 - val_loss: 0.6093
Epoch 2/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 20s 315ms/step - accuracy: 0.6584 - loss: 0.6526 - val_accuracy: 0.7995 - val_loss: 0.4505
Epoch 3/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 20s 320ms/step - accuracy: 0.7292 - loss: 0.5316 - val_accuracy: 0.8589 - val_loss: 0.3639
Epoch 4/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 20s 319ms/step - accuracy: 0.7900 - loss: 0.4497 - val_accuracy: 0.8812 - val_loss: 0.3102
Epoch 5/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 20s 322ms/step - accuracy: 0.8209 - loss: 0.4052 - val_accuracy: 0.9022 - val_loss: 0.2678
Epoch 6/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 20s 317ms/step - accuracy: 0.8428 - loss: 0.3570 - val_accuracy: 0.9220 - val_loss: 0.2337
Epoch 7/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 21s 329ms/step - accuracy: 0.8664 - loss: 0.3276 - val_accuracy: 0.9282 - val_loss: 0.2063
Epoch 8/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 21s 331ms/step - accuracy: 0.8847 - loss: 0.2943 - val_accuracy: 0.9431 - val_loss: 0.1856
Epoch 9/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 20s 322ms/step - accuracy: 0.8868 - loss: 0.2835 - val_accuracy: 0.9468 - val_loss: 0.1742
Epoch 10/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 20s 323ms/step - accuracy: 0.8829 - loss: 0.2807 - val_accuracy: 0.9443 - val_loss: 0.1777
Epoch 1/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 23s 313ms/step - accuracy: 0.6506 - loss: 0.6440 - val_accuracy: 0.8800 - val_loss: 0.3967
Epoch 2/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 20s 311ms/step - accuracy: 0.7739 - loss: 0.4787 - val_accuracy: 0.9245 - val_loss: 0.2975
Epoch 3/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 20s 314ms/step - accuracy: 0.8607 - loss: 0.3754 - val_accuracy: 0.9356 - val_loss: 0.2451
Epoch 4/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 20s 310ms/step - accuracy: 0.8586 - loss: 0.3449 - val_accuracy: 0.9480 - val_loss: 0.2093
Epoch 5/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 20s 309ms/step - accuracy: 0.8782 - loss: 0.2956 - val_accuracy: 0.9592 - val_loss: 0.1787
Epoch 6/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 19s 307ms/step - accuracy: 0.8797 - loss: 0.2901 - val_accuracy: 0.9592 - val_loss: 0.1584
Epoch 7/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 19s 304ms/step - accuracy: 0.9064 - loss: 0.2451 - val_accuracy: 0.9629 - val_loss: 0.1414
Epoch 8/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 19s 302ms/step - accuracy: 0.9054 - loss: 0.2301 - val_accuracy: 0.9666 - val_loss: 0.1313
Epoch 9/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 19s 305ms/step - accuracy: 0.9249 - loss: 0.2083 - val_accuracy: 0.9666 - val_loss: 0.1218
Epoch 10/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 31s 493ms/step - accuracy: 0.9239 - loss: 0.2087 - val_accuracy: 0.9691 - val_loss: 0.1203
Epoch 1/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 26s 314ms/step - accuracy: 0.4008 - loss: 1.0714 - val_accuracy: 0.3998 - val_loss: 0.9499
Epoch 2/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 19s 307ms/step - accuracy: 0.5127 - loss: 0.8443 - val_accuracy: 0.5767 - val_loss: 0.7257
Epoch 3/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 20s 315ms/step - accuracy: 0.6304 - loss: 0.6657 - val_accuracy: 0.6980 - val_loss: 0.5812
Epoch 4/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 21s 328ms/step - accuracy: 0.7012 - loss: 0.5739 - val_accuracy: 0.7995 - val_loss: 0.4759
Epoch 5/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 19s 301ms/step - accuracy: 0.7551 - loss: 0.5076 - val_accuracy: 0.8465 - val_loss: 0.4046
Epoch 6/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 18s 280ms/step - accuracy: 0.8137 - loss: 0.4250 - val_accuracy: 0.8923 - val_loss: 0.3287
Epoch 7/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 19s 299ms/step - accuracy: 0.8528 - loss: 0.3722 - val_accuracy: 0.9072 - val_loss: 0.2876
Epoch 8/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 19s 308ms/step - accuracy: 0.8611 - loss: 0.3463 - val_accuracy: 0.9282 - val_loss: 0.2472
Epoch 9/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 18s 288ms/step - accuracy: 0.8843 - loss: 0.3108 - val_accuracy: 0.9369 - val_loss: 0.2301
Epoch 10/10
63/63 ━━━━━━━━━━━━━━━━━━━━ 20s 310ms/step - accuracy: 0.8820 - loss: 0.2883 - val_accuracy: 0.9418 - val_loss: 0.2102

Learning curves¶

Let's take a look at the learning curves of the training and validation accuracy/loss when using the MobileNetV2 base model as a fixed feature extractor.

In [ ]:
# Learning curves for MobileNet
acc_v1 = history_v1.history['accuracy']
val_acc_v1 = history_v1.history['val_accuracy']

loss_v1 = history_v1.history['loss']
val_loss_v1 = history_v1.history['val_loss']

plt.figure(figsize=(8, 8))
plt.subplot(2, 1, 1)
plt.plot(acc_v1, label='MobileNet Training Accuracy')
plt.plot(val_acc_v1, label='MobileNet Validation Accuracy')
plt.legend(loc='lower right')
plt.ylabel('Accuracy')
plt.ylim([min(plt.ylim()), 1])
plt.title('MobileNet Training and Validation Accuracy')

plt.subplot(2, 1, 2)
plt.plot(loss_v1, label='MobileNet Training Loss')
plt.plot(val_loss_v1, label='MobileNet Validation Loss')
plt.legend(loc='upper right')
plt.ylabel('Cross Entropy')
plt.ylim([0, 1.0])
plt.title('MobileNet Training and Validation Loss')
plt.xlabel('epoch')
plt.show()


# Learning curves for MobileNet V2
acc_v2 = history_v2.history['accuracy']
val_acc_v2 = history_v2.history['val_accuracy']

loss_v2 = history_v2.history['loss']
val_loss_v2 = history_v2.history['val_loss']

plt.figure(figsize=(8, 8))
plt.subplot(2, 1, 1)
plt.plot(acc_v2, label='MobileNet V2 Training Accuracy')
plt.plot(val_acc_v2, label='MobileNet V2 Validation Accuracy')
plt.legend(loc='lower right')
plt.ylabel('Accuracy')
plt.ylim([min(plt.ylim()), 1])
plt.title('MobileNet V2 Training and Validation Accuracy')

plt.subplot(2, 1, 2)
plt.plot(loss_v2, label='MobileNet V2 Training Loss')
plt.plot(val_loss_v2, label='MobileNet V2 Validation Loss')
plt.legend(loc='upper right')
plt.ylabel('Cross Entropy')
plt.ylim([0, 1.0])
plt.title('MobileNet V2 Training and Validation Loss')
plt.xlabel('epoch')
plt.show()


# Learning curves for MobileNet V3
acc_v3 = history_v3.history['accuracy']
val_acc_v3 = history_v3.history['val_accuracy']

loss_v3 = history_v3.history['loss']
val_loss_v3 = history_v3.history['val_loss']

plt.figure(figsize=(8, 8))
plt.subplot(2, 1, 1)
plt.plot(acc_v3, label='MobileNet V3 Training Accuracy')
plt.plot(val_acc_v3, label='MobileNet V3 Validation Accuracy')
plt.legend(loc='lower right')
plt.ylabel('Accuracy')
plt.ylim([min(plt.ylim()), 1])
plt.title('MobileNet V3 Training and Validation Accuracy')

plt.subplot(2, 1, 2)
plt.plot(loss_v3, label='MobileNet V3 Training Loss')
plt.plot(val_loss_v3, label='MobileNet V3 Validation Loss')
plt.legend(loc='upper right')
plt.ylabel('Cross Entropy')
plt.ylim([0, 1.0])
plt.title('MobileNet V3 Training and Validation Loss')
plt.xlabel('epoch')
plt.show()

Note: If you are wondering why the validation metrics are clearly better than the training metrics, the main factor is because layers like tf.keras.layers.BatchNormalization and tf.keras.layers.Dropout affect accuracy during training. They are turned off when calculating validation loss.

To a lesser extent, it is also because training metrics report the average for an epoch, while validation metrics are evaluated after the epoch, so validation metrics see a model that has trained slightly longer.

Fine tuning¶

In the feature extraction experiment, you were only training a few layers on top of an MobileNetV2 base model. The weights of the pre-trained network were not updated during training.

One way to increase performance even further is to train (or "fine-tune") the weights of the top layers of the pre-trained model alongside the training of the classifier you added. The training process will force the weights to be tuned from generic feature maps to features associated specifically with the dataset.

Note: This should only be attempted after you have trained the top-level classifier with the pre-trained model set to non-trainable. If you add a randomly initialized classifier on top of a pre-trained model and attempt to train all layers jointly, the magnitude of the gradient updates will be too large (due to the random weights from the classifier) and your pre-trained model will forget what it has learned.

Also, you should try to fine-tune a small number of top layers rather than the whole MobileNet model. In most convolutional networks, the higher up a layer is, the more specialized it is. The first few layers learn very simple and generic features that generalize to almost all types of images. As you go higher up, the features are increasingly more specific to the dataset on which the model was trained. The goal of fine-tuning is to adapt these specialized features to work with the new dataset, rather than overwrite the generic learning.

Un-freeze the top layers of the model¶

All you need to do is unfreeze the base_model and set the bottom layers to be un-trainable. Then, you should recompile the model (necessary for these changes to take effect), and resume training.

In [ ]:
# Un-freeze the top layers of the MobileNet model
base_model_v1.trainable = True

# Un-freeze the top layers of the MobileNet V2 model
base_model_v2.trainable = True

# Un-freeze the top layers of the MobileNet V3 model
base_model_v3.trainable = True
In [ ]:
# Look at the number of layers for both models
print("Number of layers in the MobileNet base model: ", len(base_model_v1.layers))
print("Number of layers in the MobileNet V2 base model: ", len(base_model_v2.layers))
print("Number of layers in the MobileNet V3 base model: ", len(base_model_v3.layers))

# Fine-tune from this layer onwards for both models
fine_tune_at = 100

# Freeze all the layers before the `fine_tune_at` layer for MobileNet
for layer in base_model_v1.layers[:fine_tune_at]:
    layer.trainable = False

# Freeze all the layers before the `fine_tune_at` layer for MobileNet V2
for layer in base_model_v2.layers[:fine_tune_at]:
    layer.trainable = False
    
# Freeze all the layers before the `fine_tune_at` layer for MobileNet V3
for layer in base_model_v3.layers[:fine_tune_at]:
    layer.trainable = False
Number of layers in the MobileNet base model:  86
Number of layers in the MobileNet V2 base model:  154
Number of layers in the MobileNet V3 base model:  187

Compile the model¶

As you are training a much larger model and want to readapt the pretrained weights, it is important to use a lower learning rate at this stage. Otherwise, your model could overfit very quickly.

In [ ]:
# Compile the model for MobileNet
model_v1.compile(loss=tf.keras.losses.BinaryCrossentropy(),
              optimizer=tf.keras.optimizers.RMSprop(learning_rate=base_learning_rate / 10),
              metrics=[tf.keras.metrics.BinaryAccuracy(threshold=0.5, name='accuracy')])

# Compile the model for MobileNet V2
model_v2.compile(loss=tf.keras.losses.BinaryCrossentropy(),
              optimizer=tf.keras.optimizers.RMSprop(learning_rate=base_learning_rate / 10),
              metrics=[tf.keras.metrics.BinaryAccuracy(threshold=0.5, name='accuracy')])

# Compile the model for MobileNet V3
model_v3.compile(loss=tf.keras.losses.BinaryCrossentropy(),
              optimizer=tf.keras.optimizers.RMSprop(learning_rate=base_learning_rate / 10),
              metrics=[tf.keras.metrics.BinaryAccuracy(threshold=0.5, name='accuracy')])
In [ ]:
print("\nMobileNet Model Summary")
model_v1.summary()

print("MobileNet V2 Model Summary")
model_v2.summary()

print("MobileNet V3 Model Summary")
model_v3.summary()
MobileNet Model Summary
Model: "functional_57"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type)                    ┃ Output Shape           ┃       Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ input_layer_39 (InputLayer)     │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ sequential_5 (Sequential)       │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ true_divide_16 (TrueDivide)     │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ subtract_16 (Subtract)          │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ mobilenet_1.00_160 (Functional) │ (None, 5, 5, 1024)     │     3,228,864 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ global_average_pooling2d_11     │ (None, 1024)           │             0 │
│ (GlobalAveragePooling2D)        │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_28 (Dropout)            │ (None, 1024)           │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_19 (Dense)                │ (None, 1)              │         1,025 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
 Total params: 3,229,889 (12.32 MB)
 Trainable params: 1,025 (4.00 KB)
 Non-trainable params: 3,228,864 (12.32 MB)
MobileNet V2 Model Summary
Model: "functional_59"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type)                    ┃ Output Shape           ┃       Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ input_layer_39 (InputLayer)     │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ sequential_5 (Sequential)       │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ true_divide_17 (TrueDivide)     │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ subtract_17 (Subtract)          │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ mobilenetv2_1.00_160            │ (None, 5, 5, 1280)     │     2,257,984 │
│ (Functional)                    │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ global_average_pooling2d_12     │ (None, 1280)           │             0 │
│ (GlobalAveragePooling2D)        │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_29 (Dropout)            │ (None, 1280)           │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_20 (Dense)                │ (None, 1)              │         1,281 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
 Total params: 2,259,265 (8.62 MB)
 Trainable params: 1,862,721 (7.11 MB)
 Non-trainable params: 396,544 (1.51 MB)
MobileNet V3 Model Summary
Model: "functional_61"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓
┃ Layer (type)                    ┃ Output Shape           ┃       Param # ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩
│ input_layer_39 (InputLayer)     │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ sequential_5 (Sequential)       │ (None, 160, 160, 3)    │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ MobilenetV3large (Functional)   │ (None, 5, 5, 960)      │     2,996,352 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ global_average_pooling2d_13     │ (None, 960)            │             0 │
│ (GlobalAveragePooling2D)        │                        │               │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dropout_30 (Dropout)            │ (None, 960)            │             0 │
├─────────────────────────────────┼────────────────────────┼───────────────┤
│ dense_21 (Dense)                │ (None, 1)              │           961 │
└─────────────────────────────────┴────────────────────────┴───────────────┘
 Total params: 2,997,313 (11.43 MB)
 Trainable params: 2,812,961 (10.73 MB)
 Non-trainable params: 184,352 (720.12 KB)

Continue training the model¶

If you trained to convergence earlier, this step will improve your accuracy by a few percentage points.

In [ ]:
# Continue training the model for MobileNet V2
fine_tune_epochs = 10
total_epochs = initial_epochs + fine_tune_epochs

# Continue training the model for MobileNet
history_fine_v1 = model_v1.fit(train_dataset,
                            epochs=total_epochs,
                            initial_epoch=history_v1.epoch[-1],
                            validation_data=validation_dataset)

history_fine_v2 = model_v2.fit(train_dataset,
                         epochs=total_epochs,
                         initial_epoch=history_v2.epoch[-1],
                         validation_data=validation_dataset)

history_fine_v3 = model_v3.fit(train_dataset,
                            epochs=total_epochs,
                            initial_epoch=history_v3.epoch[-1],
                            validation_data=validation_dataset)
Epoch 10/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 24s 341ms/step - accuracy: 0.9057 - loss: 0.2478 - val_accuracy: 0.9554 - val_loss: 0.1522
Epoch 11/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 28s 439ms/step - accuracy: 0.8917 - loss: 0.2504 - val_accuracy: 0.9579 - val_loss: 0.1500
Epoch 12/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 31s 488ms/step - accuracy: 0.8969 - loss: 0.2490 - val_accuracy: 0.9530 - val_loss: 0.1566
Epoch 13/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 25s 393ms/step - accuracy: 0.9047 - loss: 0.2435 - val_accuracy: 0.9517 - val_loss: 0.1556
Epoch 14/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 26s 416ms/step - accuracy: 0.8989 - loss: 0.2489 - val_accuracy: 0.9530 - val_loss: 0.1585
Epoch 15/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 26s 416ms/step - accuracy: 0.9077 - loss: 0.2462 - val_accuracy: 0.9554 - val_loss: 0.1534
Epoch 16/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 24s 375ms/step - accuracy: 0.9103 - loss: 0.2318 - val_accuracy: 0.9554 - val_loss: 0.1474
Epoch 17/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 27s 424ms/step - accuracy: 0.8903 - loss: 0.2484 - val_accuracy: 0.9592 - val_loss: 0.1484
Epoch 18/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 22s 349ms/step - accuracy: 0.9097 - loss: 0.2409 - val_accuracy: 0.9530 - val_loss: 0.1488
Epoch 19/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 25s 395ms/step - accuracy: 0.9114 - loss: 0.2261 - val_accuracy: 0.9554 - val_loss: 0.1432
Epoch 20/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 27s 424ms/step - accuracy: 0.9001 - loss: 0.2340 - val_accuracy: 0.9530 - val_loss: 0.1486
Epoch 10/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 41s 522ms/step - accuracy: 0.7697 - loss: 0.4553 - val_accuracy: 0.9728 - val_loss: 0.0906
Epoch 11/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 33s 523ms/step - accuracy: 0.8720 - loss: 0.2964 - val_accuracy: 0.9728 - val_loss: 0.0739
Epoch 12/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 32s 510ms/step - accuracy: 0.9159 - loss: 0.2066 - val_accuracy: 0.9728 - val_loss: 0.0668
Epoch 13/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 31s 497ms/step - accuracy: 0.9213 - loss: 0.1877 - val_accuracy: 0.9814 - val_loss: 0.0570
Epoch 14/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 35s 555ms/step - accuracy: 0.9280 - loss: 0.1755 - val_accuracy: 0.9814 - val_loss: 0.0542
Epoch 15/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 28s 443ms/step - accuracy: 0.9416 - loss: 0.1451 - val_accuracy: 0.9839 - val_loss: 0.0466
Epoch 16/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 30s 474ms/step - accuracy: 0.9527 - loss: 0.1373 - val_accuracy: 0.9839 - val_loss: 0.0466
Epoch 17/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 32s 510ms/step - accuracy: 0.9496 - loss: 0.1526 - val_accuracy: 0.9851 - val_loss: 0.0463
Epoch 18/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 37s 589ms/step - accuracy: 0.9432 - loss: 0.1389 - val_accuracy: 0.9876 - val_loss: 0.0436
Epoch 19/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 37s 583ms/step - accuracy: 0.9592 - loss: 0.1053 - val_accuracy: 0.9851 - val_loss: 0.0437
Epoch 20/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 34s 538ms/step - accuracy: 0.9640 - loss: 0.0967 - val_accuracy: 0.9839 - val_loss: 0.0547
Epoch 10/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 40s 460ms/step - accuracy: 0.7797 - loss: 0.4476 - val_accuracy: 0.9604 - val_loss: 0.1687
Epoch 11/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 27s 435ms/step - accuracy: 0.8284 - loss: 0.3722 - val_accuracy: 0.9530 - val_loss: 0.1596
Epoch 12/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 32s 515ms/step - accuracy: 0.8598 - loss: 0.3377 - val_accuracy: 0.9604 - val_loss: 0.1427
Epoch 13/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 31s 484ms/step - accuracy: 0.8669 - loss: 0.3147 - val_accuracy: 0.9579 - val_loss: 0.1301
Epoch 14/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 27s 432ms/step - accuracy: 0.8849 - loss: 0.2885 - val_accuracy: 0.9641 - val_loss: 0.1266
Epoch 15/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 27s 435ms/step - accuracy: 0.8877 - loss: 0.2593 - val_accuracy: 0.9616 - val_loss: 0.1220
Epoch 16/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 27s 427ms/step - accuracy: 0.8986 - loss: 0.2459 - val_accuracy: 0.9592 - val_loss: 0.1120
Epoch 17/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 27s 432ms/step - accuracy: 0.9057 - loss: 0.2289 - val_accuracy: 0.9666 - val_loss: 0.0996
Epoch 18/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 28s 442ms/step - accuracy: 0.9244 - loss: 0.2041 - val_accuracy: 0.9641 - val_loss: 0.0984
Epoch 19/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 34s 537ms/step - accuracy: 0.9154 - loss: 0.2082 - val_accuracy: 0.9653 - val_loss: 0.1046
Epoch 20/20
63/63 ━━━━━━━━━━━━━━━━━━━━ 29s 463ms/step - accuracy: 0.9259 - loss: 0.1962 - val_accuracy: 0.9629 - val_loss: 0.0992

Let's take a look at the learning curves of the training and validation accuracy/loss when fine-tuning the last few layers of the MobileNetV2 base model and training the classifier on top of it. The validation loss is much higher than the training loss, so you may get some overfitting.

You may also get some overfitting as the new training set is relatively small and similar to the original MobileNetV2 datasets.

After fine tuning the model nearly reaches 98% accuracy on the validation set.

In [ ]:
# MobileNet
acc_v1 += history_fine_v1.history['accuracy']
val_acc_v1 += history_fine_v1.history['val_accuracy']

loss_v1 += history_fine_v1.history['loss']
val_loss_v1 += history_fine_v1.history['val_loss']

# MobileNet V2
acc_v2 += history_fine_v2.history['accuracy']
val_acc_v2 += history_fine_v2.history['val_accuracy']

loss_v2 += history_fine_v2.history['loss']
val_loss_v2 += history_fine_v2.history['val_loss']

# MobileNet V3
acc_v3 += history_fine_v3.history['accuracy']
val_acc_v3 += history_fine_v3.history['val_accuracy']

loss_v3 += history_fine_v3.history['loss']
val_loss_v3 += history_fine_v3.history['val_loss']
In [ ]:
# Plotting for MobileNet
plt.figure(figsize=(16, 16))
plt.subplot(3, 2, 1) 
plt.plot(acc_v1, label='MobileNet Training Accuracy')
plt.plot(val_acc_v1, label='MobileNet Validation Accuracy')
plt.ylim([0.8, 1])
plt.plot([initial_epochs-1,initial_epochs-1],
         plt.ylim(), label='Start Fine Tuning') # Add a vertical line to highlight the start of fine-tuning
plt.legend(loc='lower right')
plt.title('MobileNet Training and Validation Accuracy')

plt.subplot(3, 2, 2) 
plt.plot(loss_v1, label='MobileNet Training Loss')
plt.plot(val_loss_v1, label='MobileNet Validation Loss')
plt.ylim([0, 1.0])
plt.plot([initial_epochs-1,initial_epochs-1],
         plt.ylim(), label='Start Fine Tuning') # Add a vertical line to highlight the start of fine-tuning
plt.legend(loc='upper right')
plt.title('MobileNet Training and Validation Loss')

# Plotting for MobileNet V2
plt.figure(figsize=(16, 16))
plt.subplot(3, 2, 3) 
plt.plot(acc_v2, label='MobileNet V2 Training Accuracy')
plt.plot(val_acc_v2, label='MobileNet V2 Validation Accuracy')
plt.ylim([0.8, 1])
plt.plot([initial_epochs-1,initial_epochs-1],
         plt.ylim(), label='Start Fine Tuning') # Add a vertical line to highlight the start of fine-tuning
plt.legend(loc='lower right')
plt.title('MobileNet V2 Training and Validation Accuracy')

plt.subplot(3, 2, 4) 
plt.plot(loss_v2, label='MobileNet V2 Training Loss')
plt.plot(val_loss_v2, label='MobileNet V2 Validation Loss')
plt.ylim([0, 1.0])
plt.plot([initial_epochs-1,initial_epochs-1],
         plt.ylim(), label='Start Fine Tuning') # Add a vertical line to highlight the start of fine-tuning
plt.legend(loc='upper right')
plt.title('MobileNet V2 Training and Validation Loss')

# Plotting for MobileNet V3
plt.figure(figsize=(16, 16))
plt.subplot(3, 2, 5) 
plt.plot(acc_v3, label='MobileNet V3 Training Accuracy')
plt.plot(val_acc_v3, label='MobileNet V3 Validation Accuracy')
plt.ylim([0.8, 1])
plt.plot([initial_epochs-1,initial_epochs-1],
         plt.ylim(), label='Start Fine Tuning') # Add a vertical line to highlight the start of fine-tuning
plt.legend(loc='lower right')
plt.title('MobileNet V3 Training and Validation Accuracy')

plt.subplot(3, 2, 6) 
plt.plot(loss_v3, label='MobileNet V3 Training Loss')
plt.plot(val_loss_v3, label='MobileNet V3 Validation Loss')
plt.ylim([0, 1.0])
plt.plot([initial_epochs-1,initial_epochs-1],
         plt.ylim(), label='Start Fine Tuning') # Add a vertical line to highlight the start of fine-tuning
plt.legend(loc='upper right')
plt.title('MobileNet V3 Training and Validation Loss')
Out[ ]:
Text(0.5, 1.0, 'MobileNet V3 Training and Validation Loss')

Evaluation and prediction¶

Finally you can verify the performance of the model on new data using test set.

In [ ]:
# Evaluate MobileNet model
loss_v1, accuracy_v1 = model_v1.evaluate(test_dataset)
print('MobileNet Test accuracy :', accuracy_v1)

# Evaluate MobileNet V2 model
loss_v2, accuracy_v2 = model_v2.evaluate(test_dataset)
print('MobileNet V2 Test accuracy :', accuracy_v2)

# Evaluate MobileNet V3 model
loss_v3, accuracy_v3 = model_v3.evaluate(test_dataset)
print('MobileNet V3 Test accuracy :', accuracy_v3)
6/6 ━━━━━━━━━━━━━━━━━━━━ 1s 217ms/step - accuracy: 0.9417 - loss: 0.1639
MobileNet Test accuracy : 0.9479166865348816
6/6 ━━━━━━━━━━━━━━━━━━━━ 1s 197ms/step - accuracy: 0.9976 - loss: 0.0202
MobileNet V2 Test accuracy : 0.9947916865348816
6/6 ━━━━━━━━━━━━━━━━━━━━ 1s 170ms/step - accuracy: 0.9714 - loss: 0.0850
MobileNet V3 Test accuracy : 0.9739583134651184

And now you are all set to use this model to predict if your pet is a cat or dog.

In [ ]:
# Retrieve a batch of images from the test set
image_batch, label_batch = test_dataset.as_numpy_iterator().next()

# Predict with MobileNet
predictions_v1 = model_v1.predict_on_batch(image_batch).flatten()
predictions_v1 = tf.nn.sigmoid(predictions_v1)
predictions_v1 = tf.where(predictions_v1 < 0.5, 0, 1)

# Predict with MobileNet V2
predictions_v2 = model_v2.predict_on_batch(image_batch).flatten()
predictions_v2 = tf.nn.sigmoid(predictions_v2)
predictions_v2 = tf.where(predictions_v2 < 0.5, 0, 1)

# Predict with MobileNet V3
predictions_v3 = model_v3.predict_on_batch(image_batch).flatten()
predictions_v3 = tf.nn.sigmoid(predictions_v3)
predictions_v3 = tf.where(predictions_v3 < 0.5, 0, 1)

print('MobileNet Predictions:\n', predictions_v1.numpy())
print('MobileNet V2 Predictions:\n', predictions_v2.numpy())
print('MobileNet V3 Predictions:\n', predictions_v3.numpy())

print('Labels:\n', label_batch)

print("MobileNet Predictions")
plt.figure(figsize=(10, 10))
for i in range(9):
    ax = plt.subplot(3, 3, i + 1)
    plt.imshow(image_batch[i].astype("uint8"))
    plt.title(class_names[predictions_v1[i]])
    plt.axis("off")

print("MobileNet V2 Predictions")
plt.figure(figsize=(10, 10))
for i in range(9):
    ax = plt.subplot(3, 3, i + 1)
    plt.imshow(image_batch[i].astype("uint8"))
    plt.title(class_names[predictions_v2[i]])
    plt.axis("off")
    
print("MobileNet V3 Predictions")
plt.figure(figsize=(10, 10))
for i in range(9):
    ax = plt.subplot(3, 3, i + 1)
    plt.imshow(image_batch[i].astype("uint8"))
    plt.title(class_names[predictions_v3[i]])
    plt.axis("off")
WARNING:tensorflow:5 out of the last 5 calls to <function TensorFlowTrainer.make_predict_function.<locals>.one_step_on_data_distributed at 0x14a26a020> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has reduce_retracing=True option that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for  more details.
WARNING:tensorflow:6 out of the last 6 calls to <function TensorFlowTrainer.make_predict_function.<locals>.one_step_on_data_distributed at 0x2a1304220> triggered tf.function retracing. Tracing is expensive and the excessive number of tracings could be due to (1) creating @tf.function repeatedly in a loop, (2) passing tensors with different shapes, (3) passing Python objects instead of tensors. For (1), please define your @tf.function outside of the loop. For (2), @tf.function has reduce_retracing=True option that can avoid unnecessary retracing. For (3), please refer to https://www.tensorflow.org/guide/function#controlling_retracing and https://www.tensorflow.org/api_docs/python/tf/function for  more details.
MobileNet Predictions:
 [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
MobileNet V2 Predictions:
 [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
MobileNet V3 Predictions:
 [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
Labels:
 [0 0 1 1 0 0 0 1 1 0 1 0 0 1 0 0 0 1 0 1 1 0 1 1 0 0 1 1 1 1 1 1]
MobileNet Predictions
MobileNet V2 Predictions
MobileNet V3 Predictions

Summary¶

  • Using a pre-trained model for feature extraction: When working with a small dataset, it is a common practice to take advantage of features learned by a model trained on a larger dataset in the same domain. This is done by instantiating the pre-trained model and adding a fully-connected classifier on top. The pre-trained model is "frozen" and only the weights of the classifier get updated during training. In this case, the convolutional base extracted all the features associated with each image and you just trained a classifier that determines the image class given that set of extracted features.

  • Fine-tuning a pre-trained model: To further improve performance, one might want to repurpose the top-level layers of the pre-trained models to the new dataset via fine-tuning. In this case, you tuned your weights such that your model learned high-level features specific to the dataset. This technique is usually recommended when the training dataset is large and very similar to the original dataset that the pre-trained model was trained on.

To learn more, visit the Transfer learning guide.

Conclusion¶

The comparison of prediction results from MobileNet, MobileNet V2, and MobileNet V3 models on a batch of images from a test dataset yields an intriguing insight into the performance and behavior of these architectures.

  • MobileNet: The original MobileNet architecture, designed for efficiency and speed, seems to predict the majority of the test images as belonging to one class (in this case, class 1). This could indicate a bias or overfitting towards one class, possibly due to its simpler architecture compared to its successors.

  • MobileNet V2: Similar to MobileNet, MobileNet V2 also predicts all test images as class 1. While MobileNet V2 introduces improvements over the original MobileNet, including the inverted residual structure that allows for better feature representation, the predictions suggest that it might also be overly confident or biased towards one class in this particular test set.

  • MobileNet V3: Continuing the trend, MobileNet V3—which incorporates further enhancements for efficiency and performance—also classifies all test images as class 1. MobileNet V3's optimizations, including the use of squeeze-and-excitation and hard-swish activation functions, were expected to provide more nuanced predictions. However, the results indicate a similar bias or overfitting issue as seen with the previous models.

Across all three models, the uniform prediction of all test images as belonging to one class, despite the actual labels varying between classes 0 and 1, highlights a critical issue. This could be indicative of overfitting, where the models have learned to favor one class possibly due to imbalances or peculiarities in the training dataset. Alternatively, it may reflect a limitation in the models' ability to generalize from the training data to new, unseen images.

Discussion¶

  • Model Bias and Overfitting: The uniform prediction results suggest that all three models may suffer from bias towards one class. This could be due to several factors, including imbalanced training data, insufficient model complexity to capture the nuances between classes, or inadequate training (e.g., not enough epochs or inappropriate learning rate).

  • Model Generalization: Despite their architectural differences and optimizations, all three models failed to generalize well to the test data. This raises questions about the diversity and representativeness of the training dataset and whether the models were adequately validated during training.

  • Future Directions: Improving the models' performance could involve several strategies. Firstly, ensuring a balanced and representative training dataset is crucial. Secondly, experimenting with different training parameters (e.g., learning rates, batch sizes) and regularization techniques (e.g., dropout, data augmentation) might help mitigate overfitting. Lastly, employing model evaluation techniques such as cross-validation could provide more insights into the models' ability to generalize and guide further optimizations.

In summary, while MobileNet, MobileNet V2, and MobileNet V3 are potent architectures designed for efficient and effective image classification, their performance in this particular test scenario highlights the importance of comprehensive dataset preparation, careful model training, and rigorous validation to achieve accurate and generalizable prediction results.

References¶

  • Transfer learning and fine-tuning: https://www.tensorflow.org/tutorials/images/transfer_learning
  • mobilenet module: https://www.tensorflow.org/api_docs/python/tf/keras/applications/mobilenet
  • mobilenet_v2 module: https://www.tensorflow.org/api_docs/python/tf/keras/applications/mobilenet_v2
  • mobilenet_v3 module: https://www.tensorflow.org/api_docs/python/tf/keras/applications/mobilenet_v3
In [ ]:
 
In [ ]: